1package org.bouncycastle.util;
2
3import java.math.BigInteger;
4import java.util.NoSuchElementException;
5
6/**
7 * General array utilities.
8 */
9public final class Arrays
10{
11    private Arrays()
12    {
13        // static class, hide constructor
14    }
15
16    public static boolean areEqual(
17        boolean[]  a,
18        boolean[]  b)
19    {
20        if (a == b)
21        {
22            return true;
23        }
24
25        if (a == null || b == null)
26        {
27            return false;
28        }
29
30        if (a.length != b.length)
31        {
32            return false;
33        }
34
35        for (int i = 0; i != a.length; i++)
36        {
37            if (a[i] != b[i])
38            {
39                return false;
40            }
41        }
42
43        return true;
44    }
45
46    public static boolean areEqual(
47        char[]  a,
48        char[]  b)
49    {
50        if (a == b)
51        {
52            return true;
53        }
54
55        if (a == null || b == null)
56        {
57            return false;
58        }
59
60        if (a.length != b.length)
61        {
62            return false;
63        }
64
65        for (int i = 0; i != a.length; i++)
66        {
67            if (a[i] != b[i])
68            {
69                return false;
70            }
71        }
72
73        return true;
74    }
75
76    public static boolean areEqual(
77        byte[]  a,
78        byte[]  b)
79    {
80        if (a == b)
81        {
82            return true;
83        }
84
85        if (a == null || b == null)
86        {
87            return false;
88        }
89
90        if (a.length != b.length)
91        {
92            return false;
93        }
94
95        for (int i = 0; i != a.length; i++)
96        {
97            if (a[i] != b[i])
98            {
99                return false;
100            }
101        }
102
103        return true;
104    }
105
106    public static boolean areEqual(
107        short[]  a,
108        short[]  b)
109    {
110        if (a == b)
111        {
112            return true;
113        }
114
115        if (a == null || b == null)
116        {
117            return false;
118        }
119
120        if (a.length != b.length)
121        {
122            return false;
123        }
124
125        for (int i = 0; i != a.length; i++)
126        {
127            if (a[i] != b[i])
128            {
129                return false;
130            }
131        }
132
133        return true;
134    }
135
136    /**
137     * A constant time equals comparison - does not terminate early if
138     * test will fail.
139     *
140     * @param a first array
141     * @param b second array
142     * @return true if arrays equal, false otherwise.
143     */
144    public static boolean constantTimeAreEqual(
145        byte[]  a,
146        byte[]  b)
147    {
148        if (a == b)
149        {
150            return true;
151        }
152
153        if (a == null || b == null)
154        {
155            return false;
156        }
157
158        if (a.length != b.length)
159        {
160            return false;
161        }
162
163        int nonEqual = 0;
164
165        for (int i = 0; i != a.length; i++)
166        {
167            nonEqual |= (a[i] ^ b[i]);
168        }
169
170        return nonEqual == 0;
171    }
172
173    public static boolean areEqual(
174        int[]  a,
175        int[]  b)
176    {
177        if (a == b)
178        {
179            return true;
180        }
181
182        if (a == null || b == null)
183        {
184            return false;
185        }
186
187        if (a.length != b.length)
188        {
189            return false;
190        }
191
192        for (int i = 0; i != a.length; i++)
193        {
194            if (a[i] != b[i])
195            {
196                return false;
197            }
198        }
199
200        return true;
201    }
202
203    public static boolean areEqual(
204        long[]  a,
205        long[]  b)
206    {
207        if (a == b)
208        {
209            return true;
210        }
211
212        if (a == null || b == null)
213        {
214            return false;
215        }
216
217        if (a.length != b.length)
218        {
219            return false;
220        }
221
222        for (int i = 0; i != a.length; i++)
223        {
224            if (a[i] != b[i])
225            {
226                return false;
227            }
228        }
229
230        return true;
231    }
232
233    public static boolean areEqual(Object[] a, Object[] b)
234    {
235        if (a == b)
236        {
237            return true;
238        }
239        if (a == null || b == null)
240        {
241            return false;
242        }
243        if (a.length != b.length)
244        {
245            return false;
246        }
247        for (int i = 0; i != a.length; i++)
248        {
249            Object objA = a[i], objB = b[i];
250            if (objA == null)
251            {
252                if (objB != null)
253                {
254                    return false;
255                }
256            }
257            else if (!objA.equals(objB))
258            {
259                return false;
260            }
261        }
262        return true;
263    }
264
265    public static int compareUnsigned(byte[] a, byte[] b)
266    {
267        if (a == b)
268        {
269            return 0;
270        }
271        if (a == null)
272        {
273            return -1;
274        }
275        if (b == null)
276        {
277            return 1;
278        }
279        int minLen = Math.min(a.length, b.length);
280        for (int i = 0; i < minLen; ++i)
281        {
282            int aVal = a[i] & 0xFF, bVal = b[i] & 0xFF;
283            if (aVal < bVal)
284            {
285                return -1;
286            }
287            if (aVal > bVal)
288            {
289                return 1;
290            }
291        }
292        if (a.length < b.length)
293        {
294            return -1;
295        }
296        if (a.length > b.length)
297        {
298            return 1;
299        }
300        return 0;
301    }
302
303    public static boolean contains(short[] a, short n)
304    {
305        for (int i = 0; i < a.length; ++i)
306        {
307            if (a[i] == n)
308            {
309                return true;
310            }
311        }
312        return false;
313    }
314
315    public static boolean contains(int[] a, int n)
316    {
317        for (int i = 0; i < a.length; ++i)
318        {
319            if (a[i] == n)
320            {
321                return true;
322            }
323        }
324        return false;
325    }
326
327    public static void fill(
328        byte[] array,
329        byte value)
330    {
331        for (int i = 0; i < array.length; i++)
332        {
333            array[i] = value;
334        }
335    }
336
337    public static void fill(
338        char[] array,
339        char value)
340    {
341        for (int i = 0; i < array.length; i++)
342        {
343            array[i] = value;
344        }
345    }
346
347    public static void fill(
348        long[] array,
349        long value)
350    {
351        for (int i = 0; i < array.length; i++)
352        {
353            array[i] = value;
354        }
355    }
356
357    public static void fill(
358        short[] array,
359        short value)
360    {
361        for (int i = 0; i < array.length; i++)
362        {
363            array[i] = value;
364        }
365    }
366
367    public static void fill(
368        int[] array,
369        int value)
370    {
371        for (int i = 0; i < array.length; i++)
372        {
373            array[i] = value;
374        }
375    }
376
377    public static int hashCode(byte[] data)
378    {
379        if (data == null)
380        {
381            return 0;
382        }
383
384        int i = data.length;
385        int hc = i + 1;
386
387        while (--i >= 0)
388        {
389            hc *= 257;
390            hc ^= data[i];
391        }
392
393        return hc;
394    }
395
396    public static int hashCode(byte[] data, int off, int len)
397    {
398        if (data == null)
399        {
400            return 0;
401        }
402
403        int i = len;
404        int hc = i + 1;
405
406        while (--i >= 0)
407        {
408            hc *= 257;
409            hc ^= data[off + i];
410        }
411
412        return hc;
413    }
414
415    public static int hashCode(char[] data)
416    {
417        if (data == null)
418        {
419            return 0;
420        }
421
422        int i = data.length;
423        int hc = i + 1;
424
425        while (--i >= 0)
426        {
427            hc *= 257;
428            hc ^= data[i];
429        }
430
431        return hc;
432    }
433
434    public static int hashCode(int[][] ints)
435    {
436        int hc = 0;
437
438        for (int i = 0; i != ints.length; i++)
439        {
440            hc = hc * 257 + hashCode(ints[i]);
441        }
442
443        return hc;
444    }
445
446    public static int hashCode(int[] data)
447    {
448        if (data == null)
449        {
450            return 0;
451        }
452
453        int i = data.length;
454        int hc = i + 1;
455
456        while (--i >= 0)
457        {
458            hc *= 257;
459            hc ^= data[i];
460        }
461
462        return hc;
463    }
464
465    public static int hashCode(int[] data, int off, int len)
466    {
467        if (data == null)
468        {
469            return 0;
470        }
471
472        int i = len;
473        int hc = i + 1;
474
475        while (--i >= 0)
476        {
477            hc *= 257;
478            hc ^= data[off + i];
479        }
480
481        return hc;
482    }
483
484    public static int hashCode(long[] data)
485    {
486        if (data == null)
487        {
488            return 0;
489        }
490
491        int i = data.length;
492        int hc = i + 1;
493
494        while (--i >= 0)
495        {
496            long di = data[i];
497            hc *= 257;
498            hc ^= (int)di;
499            hc *= 257;
500            hc ^= (int)(di >>> 32);
501        }
502
503        return hc;
504    }
505
506    public static int hashCode(long[] data, int off, int len)
507    {
508        if (data == null)
509        {
510            return 0;
511        }
512
513        int i = len;
514        int hc = i + 1;
515
516        while (--i >= 0)
517        {
518            long di = data[off + i];
519            hc *= 257;
520            hc ^= (int)di;
521            hc *= 257;
522            hc ^= (int)(di >>> 32);
523        }
524
525        return hc;
526    }
527
528    public static int hashCode(short[][][] shorts)
529    {
530        int hc = 0;
531
532        for (int i = 0; i != shorts.length; i++)
533        {
534            hc = hc * 257 + hashCode(shorts[i]);
535        }
536
537        return hc;
538    }
539
540    public static int hashCode(short[][] shorts)
541    {
542        int hc = 0;
543
544        for (int i = 0; i != shorts.length; i++)
545        {
546            hc = hc * 257 + hashCode(shorts[i]);
547        }
548
549        return hc;
550    }
551
552    public static int hashCode(short[] data)
553    {
554        if (data == null)
555        {
556            return 0;
557        }
558
559        int i = data.length;
560        int hc = i + 1;
561
562        while (--i >= 0)
563        {
564            hc *= 257;
565            hc ^= (data[i] & 0xff);
566        }
567
568        return hc;
569    }
570
571    public static int hashCode(Object[] data)
572    {
573        if (data == null)
574        {
575            return 0;
576        }
577
578        int i = data.length;
579        int hc = i + 1;
580
581        while (--i >= 0)
582        {
583            hc *= 257;
584            hc ^= data[i].hashCode();
585        }
586
587        return hc;
588    }
589
590    public static byte[] clone(byte[] data)
591    {
592        if (data == null)
593        {
594            return null;
595        }
596        byte[] copy = new byte[data.length];
597
598        System.arraycopy(data, 0, copy, 0, data.length);
599
600        return copy;
601    }
602
603    public static char[] clone(char[] data)
604    {
605        if (data == null)
606        {
607            return null;
608        }
609        char[] copy = new char[data.length];
610
611        System.arraycopy(data, 0, copy, 0, data.length);
612
613        return copy;
614    }
615
616    public static byte[] clone(byte[] data, byte[] existing)
617    {
618        if (data == null)
619        {
620            return null;
621        }
622        if ((existing == null) || (existing.length != data.length))
623        {
624            return clone(data);
625        }
626        System.arraycopy(data, 0, existing, 0, existing.length);
627        return existing;
628    }
629
630    public static byte[][] clone(byte[][] data)
631    {
632        if (data == null)
633        {
634            return null;
635        }
636
637        byte[][] copy = new byte[data.length][];
638
639        for (int i = 0; i != copy.length; i++)
640        {
641            copy[i] = clone(data[i]);
642        }
643
644        return copy;
645    }
646
647    public static byte[][][] clone(byte[][][] data)
648    {
649        if (data == null)
650        {
651            return null;
652        }
653
654        byte[][][] copy = new byte[data.length][][];
655
656        for (int i = 0; i != copy.length; i++)
657        {
658            copy[i] = clone(data[i]);
659        }
660
661        return copy;
662    }
663
664    public static int[] clone(int[] data)
665    {
666        if (data == null)
667        {
668            return null;
669        }
670        int[] copy = new int[data.length];
671
672        System.arraycopy(data, 0, copy, 0, data.length);
673
674        return copy;
675    }
676
677    public static long[] clone(long[] data)
678    {
679        if (data == null)
680        {
681            return null;
682        }
683        long[] copy = new long[data.length];
684
685        System.arraycopy(data, 0, copy, 0, data.length);
686
687        return copy;
688    }
689
690    public static long[] clone(long[] data, long[] existing)
691    {
692        if (data == null)
693        {
694            return null;
695        }
696        if ((existing == null) || (existing.length != data.length))
697        {
698            return clone(data);
699        }
700        System.arraycopy(data, 0, existing, 0, existing.length);
701        return existing;
702    }
703
704    public static short[] clone(short[] data)
705    {
706        if (data == null)
707        {
708            return null;
709        }
710        short[] copy = new short[data.length];
711
712        System.arraycopy(data, 0, copy, 0, data.length);
713
714        return copy;
715    }
716
717    public static BigInteger[] clone(BigInteger[] data)
718    {
719        if (data == null)
720        {
721            return null;
722        }
723        BigInteger[] copy = new BigInteger[data.length];
724
725        System.arraycopy(data, 0, copy, 0, data.length);
726
727        return copy;
728    }
729
730    public static byte[] copyOf(byte[] data, int newLength)
731    {
732        byte[] tmp = new byte[newLength];
733
734        if (newLength < data.length)
735        {
736            System.arraycopy(data, 0, tmp, 0, newLength);
737        }
738        else
739        {
740            System.arraycopy(data, 0, tmp, 0, data.length);
741        }
742
743        return tmp;
744    }
745
746    public static char[] copyOf(char[] data, int newLength)
747    {
748        char[] tmp = new char[newLength];
749
750        if (newLength < data.length)
751        {
752            System.arraycopy(data, 0, tmp, 0, newLength);
753        }
754        else
755        {
756            System.arraycopy(data, 0, tmp, 0, data.length);
757        }
758
759        return tmp;
760    }
761
762    public static int[] copyOf(int[] data, int newLength)
763    {
764        int[] tmp = new int[newLength];
765
766        if (newLength < data.length)
767        {
768            System.arraycopy(data, 0, tmp, 0, newLength);
769        }
770        else
771        {
772            System.arraycopy(data, 0, tmp, 0, data.length);
773        }
774
775        return tmp;
776    }
777
778    public static long[] copyOf(long[] data, int newLength)
779    {
780        long[] tmp = new long[newLength];
781
782        if (newLength < data.length)
783        {
784            System.arraycopy(data, 0, tmp, 0, newLength);
785        }
786        else
787        {
788            System.arraycopy(data, 0, tmp, 0, data.length);
789        }
790
791        return tmp;
792    }
793
794    public static BigInteger[] copyOf(BigInteger[] data, int newLength)
795    {
796        BigInteger[] tmp = new BigInteger[newLength];
797
798        if (newLength < data.length)
799        {
800            System.arraycopy(data, 0, tmp, 0, newLength);
801        }
802        else
803        {
804            System.arraycopy(data, 0, tmp, 0, data.length);
805        }
806
807        return tmp;
808    }
809
810    /**
811     * Make a copy of a range of bytes from the passed in data array. The range can
812     * extend beyond the end of the input array, in which case the return array will
813     * be padded with zeroes.
814     *
815     * @param data the array from which the data is to be copied.
816     * @param from the start index at which the copying should take place.
817     * @param to the final index of the range (exclusive).
818     *
819     * @return a new byte array containing the range given.
820     */
821    public static byte[] copyOfRange(byte[] data, int from, int to)
822    {
823        int newLength = getLength(from, to);
824
825        byte[] tmp = new byte[newLength];
826
827        if (data.length - from < newLength)
828        {
829            System.arraycopy(data, from, tmp, 0, data.length - from);
830        }
831        else
832        {
833            System.arraycopy(data, from, tmp, 0, newLength);
834        }
835
836        return tmp;
837    }
838
839    public static int[] copyOfRange(int[] data, int from, int to)
840    {
841        int newLength = getLength(from, to);
842
843        int[] tmp = new int[newLength];
844
845        if (data.length - from < newLength)
846        {
847            System.arraycopy(data, from, tmp, 0, data.length - from);
848        }
849        else
850        {
851            System.arraycopy(data, from, tmp, 0, newLength);
852        }
853
854        return tmp;
855    }
856
857    public static long[] copyOfRange(long[] data, int from, int to)
858    {
859        int newLength = getLength(from, to);
860
861        long[] tmp = new long[newLength];
862
863        if (data.length - from < newLength)
864        {
865            System.arraycopy(data, from, tmp, 0, data.length - from);
866        }
867        else
868        {
869            System.arraycopy(data, from, tmp, 0, newLength);
870        }
871
872        return tmp;
873    }
874
875    public static BigInteger[] copyOfRange(BigInteger[] data, int from, int to)
876    {
877        int newLength = getLength(from, to);
878
879        BigInteger[] tmp = new BigInteger[newLength];
880
881        if (data.length - from < newLength)
882        {
883            System.arraycopy(data, from, tmp, 0, data.length - from);
884        }
885        else
886        {
887            System.arraycopy(data, from, tmp, 0, newLength);
888        }
889
890        return tmp;
891    }
892
893    private static int getLength(int from, int to)
894    {
895        int newLength = to - from;
896        if (newLength < 0)
897        {
898            StringBuffer sb = new StringBuffer(from);
899            sb.append(" > ").append(to);
900            throw new IllegalArgumentException(sb.toString());
901        }
902        return newLength;
903    }
904
905    public static byte[] append(byte[] a, byte b)
906    {
907        if (a == null)
908        {
909            return new byte[]{ b };
910        }
911
912        int length = a.length;
913        byte[] result = new byte[length + 1];
914        System.arraycopy(a, 0, result, 0, length);
915        result[length] = b;
916        return result;
917    }
918
919    public static short[] append(short[] a, short b)
920    {
921        if (a == null)
922        {
923            return new short[]{ b };
924        }
925
926        int length = a.length;
927        short[] result = new short[length + 1];
928        System.arraycopy(a, 0, result, 0, length);
929        result[length] = b;
930        return result;
931    }
932
933    public static int[] append(int[] a, int b)
934    {
935        if (a == null)
936        {
937            return new int[]{ b };
938        }
939
940        int length = a.length;
941        int[] result = new int[length + 1];
942        System.arraycopy(a, 0, result, 0, length);
943        result[length] = b;
944        return result;
945    }
946
947    public static byte[] concatenate(byte[] a, byte[] b)
948    {
949        if (a != null && b != null)
950        {
951            byte[] rv = new byte[a.length + b.length];
952
953            System.arraycopy(a, 0, rv, 0, a.length);
954            System.arraycopy(b, 0, rv, a.length, b.length);
955
956            return rv;
957        }
958        else if (b != null)
959        {
960            return clone(b);
961        }
962        else
963        {
964            return clone(a);
965        }
966    }
967
968    public static byte[] concatenate(byte[] a, byte[] b, byte[] c)
969    {
970        if (a != null && b != null && c != null)
971        {
972            byte[] rv = new byte[a.length + b.length + c.length];
973
974            System.arraycopy(a, 0, rv, 0, a.length);
975            System.arraycopy(b, 0, rv, a.length, b.length);
976            System.arraycopy(c, 0, rv, a.length + b.length, c.length);
977
978            return rv;
979        }
980        else if (a == null)
981        {
982            return concatenate(b, c);
983        }
984        else if (b == null)
985        {
986            return concatenate(a, c);
987        }
988        else
989        {
990            return concatenate(a, b);
991        }
992    }
993
994    public static byte[] concatenate(byte[] a, byte[] b, byte[] c, byte[] d)
995    {
996        if (a != null && b != null && c != null && d != null)
997        {
998            byte[] rv = new byte[a.length + b.length + c.length + d.length];
999
1000            System.arraycopy(a, 0, rv, 0, a.length);
1001            System.arraycopy(b, 0, rv, a.length, b.length);
1002            System.arraycopy(c, 0, rv, a.length + b.length, c.length);
1003            System.arraycopy(d, 0, rv, a.length + b.length + c.length, d.length);
1004
1005            return rv;
1006        }
1007        else if (d == null)
1008        {
1009            return concatenate(a, b, c);
1010        }
1011        else if (c == null)
1012        {
1013            return concatenate(a, b, d);
1014        }
1015        else if (b == null)
1016        {
1017            return concatenate(a, c, d);
1018        }
1019        else
1020        {
1021            return concatenate(b, c, d);
1022        }
1023    }
1024
1025    public static byte[] concatenate(byte[][] arrays)
1026    {
1027        int size = 0;
1028        for (int i = 0; i != arrays.length; i++)
1029        {
1030            size += arrays[i].length;
1031        }
1032
1033        byte[] rv = new byte[size];
1034
1035        int offSet = 0;
1036        for (int i = 0; i != arrays.length; i++)
1037        {
1038            System.arraycopy(arrays[i], 0, rv, offSet, arrays[i].length);
1039            offSet += arrays[i].length;
1040        }
1041
1042        return rv;
1043    }
1044
1045    public static int[] concatenate(int[] a, int[] b)
1046    {
1047        if (a == null)
1048        {
1049            return clone(b);
1050        }
1051        if (b == null)
1052        {
1053            return clone(a);
1054        }
1055
1056        int[] c = new int[a.length + b.length];
1057        System.arraycopy(a, 0, c, 0, a.length);
1058        System.arraycopy(b, 0, c, a.length, b.length);
1059        return c;
1060    }
1061
1062    public static byte[] prepend(byte[] a, byte b)
1063    {
1064        if (a == null)
1065        {
1066            return new byte[]{ b };
1067        }
1068
1069        int length = a.length;
1070        byte[] result = new byte[length + 1];
1071        System.arraycopy(a, 0, result, 1, length);
1072        result[0] = b;
1073        return result;
1074    }
1075
1076    public static short[] prepend(short[] a, short b)
1077    {
1078        if (a == null)
1079        {
1080            return new short[]{ b };
1081        }
1082
1083        int length = a.length;
1084        short[] result = new short[length + 1];
1085        System.arraycopy(a, 0, result, 1, length);
1086        result[0] = b;
1087        return result;
1088    }
1089
1090    public static int[] prepend(int[] a, int b)
1091    {
1092        if (a == null)
1093        {
1094            return new int[]{ b };
1095        }
1096
1097        int length = a.length;
1098        int[] result = new int[length + 1];
1099        System.arraycopy(a, 0, result, 1, length);
1100        result[0] = b;
1101        return result;
1102    }
1103
1104    public static byte[] reverse(byte[] a)
1105    {
1106        if (a == null)
1107        {
1108            return null;
1109        }
1110
1111        int p1 = 0, p2 = a.length;
1112        byte[] result = new byte[p2];
1113
1114        while (--p2 >= 0)
1115        {
1116            result[p2] = a[p1++];
1117        }
1118
1119        return result;
1120    }
1121
1122    public static int[] reverse(int[] a)
1123    {
1124        if (a == null)
1125        {
1126            return null;
1127        }
1128
1129        int p1 = 0, p2 = a.length;
1130        int[] result = new int[p2];
1131
1132        while (--p2 >= 0)
1133        {
1134            result[p2] = a[p1++];
1135        }
1136
1137        return result;
1138    }
1139
1140    /**
1141     * Iterator backed by a specific array.
1142     */
1143    public static class Iterator<T>
1144        implements java.util.Iterator<T>
1145    {
1146        private final T[] dataArray;
1147
1148        private int position = 0;
1149
1150        /**
1151         * Base constructor.
1152         * <p>
1153         * Note: the array is not cloned, changes to it will affect the values returned by next().
1154         * </p>
1155         *
1156         * @param dataArray array backing the iterator.
1157         */
1158        public Iterator(T[] dataArray)
1159        {
1160            this.dataArray = dataArray;
1161        }
1162
1163        public boolean hasNext()
1164        {
1165            return position < dataArray.length;
1166        }
1167
1168        public T next()
1169        {
1170            if (position == dataArray.length)
1171            {
1172                throw new NoSuchElementException("Out of elements: " + position);
1173            }
1174
1175            return dataArray[position++];
1176        }
1177
1178        public void remove()
1179        {
1180            throw new UnsupportedOperationException("Cannot remove element from an Array.");
1181        }
1182    }
1183}
1184