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