1 package org.bouncycastle.util;
2 
3 import java.math.BigInteger;
4 import java.util.Iterator;
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(short[][][] shorts)416     public static int hashCode(short[][][] shorts)
417     {
418         int hc = 0;
419 
420         for (int i = 0; i != shorts.length; i++)
421         {
422             hc = hc * 257 + hashCode(shorts[i]);
423         }
424 
425         return hc;
426     }
427 
hashCode(short[][] shorts)428     public static int hashCode(short[][] shorts)
429     {
430         int hc = 0;
431 
432         for (int i = 0; i != shorts.length; i++)
433         {
434             hc = hc * 257 + hashCode(shorts[i]);
435         }
436 
437         return hc;
438     }
439 
hashCode(short[] data)440     public static int hashCode(short[] data)
441     {
442         if (data == null)
443         {
444             return 0;
445         }
446 
447         int i = data.length;
448         int hc = i + 1;
449 
450         while (--i >= 0)
451         {
452             hc *= 257;
453             hc ^= (data[i] & 0xff);
454         }
455 
456         return hc;
457     }
458 
hashCode(Object[] data)459     public static int hashCode(Object[] data)
460     {
461         if (data == null)
462         {
463             return 0;
464         }
465 
466         int i = data.length;
467         int hc = i + 1;
468 
469         while (--i >= 0)
470         {
471             hc *= 257;
472             hc ^= data[i].hashCode();
473         }
474 
475         return hc;
476     }
477 
clone(byte[] data)478     public static byte[] clone(byte[] data)
479     {
480         if (data == null)
481         {
482             return null;
483         }
484         byte[] copy = new byte[data.length];
485 
486         System.arraycopy(data, 0, copy, 0, data.length);
487 
488         return copy;
489     }
490 
clone(byte[] data, byte[] existing)491     public static byte[] clone(byte[] data, byte[] existing)
492     {
493         if (data == null)
494         {
495             return null;
496         }
497         if ((existing == null) || (existing.length != data.length))
498         {
499             return clone(data);
500         }
501         System.arraycopy(data, 0, existing, 0, existing.length);
502         return existing;
503     }
504 
clone(byte[][] data)505     public static byte[][] clone(byte[][] data)
506     {
507         if (data == null)
508         {
509             return null;
510         }
511 
512         byte[][] copy = new byte[data.length][];
513 
514         for (int i = 0; i != copy.length; i++)
515         {
516             copy[i] = clone(data[i]);
517         }
518 
519         return copy;
520     }
521 
clone(byte[][][] data)522     public static byte[][][] clone(byte[][][] data)
523     {
524         if (data == null)
525         {
526             return null;
527         }
528 
529         byte[][][] copy = new byte[data.length][][];
530 
531         for (int i = 0; i != copy.length; i++)
532         {
533             copy[i] = clone(data[i]);
534         }
535 
536         return copy;
537     }
538 
clone(int[] data)539     public static int[] clone(int[] data)
540     {
541         if (data == null)
542         {
543             return null;
544         }
545         int[] copy = new int[data.length];
546 
547         System.arraycopy(data, 0, copy, 0, data.length);
548 
549         return copy;
550     }
551 
clone(long[] data)552     public static long[] clone(long[] data)
553     {
554         if (data == null)
555         {
556             return null;
557         }
558         long[] copy = new long[data.length];
559 
560         System.arraycopy(data, 0, copy, 0, data.length);
561 
562         return copy;
563     }
564 
clone(long[] data, long[] existing)565     public static long[] clone(long[] data, long[] existing)
566     {
567         if (data == null)
568         {
569             return null;
570         }
571         if ((existing == null) || (existing.length != data.length))
572         {
573             return clone(data);
574         }
575         System.arraycopy(data, 0, existing, 0, existing.length);
576         return existing;
577     }
578 
clone(short[] data)579     public static short[] clone(short[] data)
580     {
581         if (data == null)
582         {
583             return null;
584         }
585         short[] copy = new short[data.length];
586 
587         System.arraycopy(data, 0, copy, 0, data.length);
588 
589         return copy;
590     }
591 
clone(BigInteger[] data)592     public static BigInteger[] clone(BigInteger[] data)
593     {
594         if (data == null)
595         {
596             return null;
597         }
598         BigInteger[] copy = new BigInteger[data.length];
599 
600         System.arraycopy(data, 0, copy, 0, data.length);
601 
602         return copy;
603     }
604 
copyOf(byte[] data, int newLength)605     public static byte[] copyOf(byte[] data, int newLength)
606     {
607         byte[] tmp = new byte[newLength];
608 
609         if (newLength < data.length)
610         {
611             System.arraycopy(data, 0, tmp, 0, newLength);
612         }
613         else
614         {
615             System.arraycopy(data, 0, tmp, 0, data.length);
616         }
617 
618         return tmp;
619     }
620 
copyOf(char[] data, int newLength)621     public static char[] copyOf(char[] data, int newLength)
622     {
623         char[] tmp = new char[newLength];
624 
625         if (newLength < data.length)
626         {
627             System.arraycopy(data, 0, tmp, 0, newLength);
628         }
629         else
630         {
631             System.arraycopy(data, 0, tmp, 0, data.length);
632         }
633 
634         return tmp;
635     }
636 
copyOf(int[] data, int newLength)637     public static int[] copyOf(int[] data, int newLength)
638     {
639         int[] tmp = new int[newLength];
640 
641         if (newLength < data.length)
642         {
643             System.arraycopy(data, 0, tmp, 0, newLength);
644         }
645         else
646         {
647             System.arraycopy(data, 0, tmp, 0, data.length);
648         }
649 
650         return tmp;
651     }
652 
copyOf(long[] data, int newLength)653     public static long[] copyOf(long[] data, int newLength)
654     {
655         long[] tmp = new long[newLength];
656 
657         if (newLength < data.length)
658         {
659             System.arraycopy(data, 0, tmp, 0, newLength);
660         }
661         else
662         {
663             System.arraycopy(data, 0, tmp, 0, data.length);
664         }
665 
666         return tmp;
667     }
668 
copyOf(BigInteger[] data, int newLength)669     public static BigInteger[] copyOf(BigInteger[] data, int newLength)
670     {
671         BigInteger[] tmp = new BigInteger[newLength];
672 
673         if (newLength < data.length)
674         {
675             System.arraycopy(data, 0, tmp, 0, newLength);
676         }
677         else
678         {
679             System.arraycopy(data, 0, tmp, 0, data.length);
680         }
681 
682         return tmp;
683     }
684 
685     /**
686      * Make a copy of a range of bytes from the passed in data array. The range can
687      * extend beyond the end of the input array, in which case the return array will
688      * be padded with zeroes.
689      *
690      * @param data the array from which the data is to be copied.
691      * @param from the start index at which the copying should take place.
692      * @param to the final index of the range (exclusive).
693      *
694      * @return a new byte array containing the range given.
695      */
copyOfRange(byte[] data, int from, int to)696     public static byte[] copyOfRange(byte[] data, int from, int to)
697     {
698         int newLength = getLength(from, to);
699 
700         byte[] tmp = new byte[newLength];
701 
702         if (data.length - from < newLength)
703         {
704             System.arraycopy(data, from, tmp, 0, data.length - from);
705         }
706         else
707         {
708             System.arraycopy(data, from, tmp, 0, newLength);
709         }
710 
711         return tmp;
712     }
713 
copyOfRange(int[] data, int from, int to)714     public static int[] copyOfRange(int[] data, int from, int to)
715     {
716         int newLength = getLength(from, to);
717 
718         int[] tmp = new int[newLength];
719 
720         if (data.length - from < newLength)
721         {
722             System.arraycopy(data, from, tmp, 0, data.length - from);
723         }
724         else
725         {
726             System.arraycopy(data, from, tmp, 0, newLength);
727         }
728 
729         return tmp;
730     }
731 
copyOfRange(long[] data, int from, int to)732     public static long[] copyOfRange(long[] data, int from, int to)
733     {
734         int newLength = getLength(from, to);
735 
736         long[] tmp = new long[newLength];
737 
738         if (data.length - from < newLength)
739         {
740             System.arraycopy(data, from, tmp, 0, data.length - from);
741         }
742         else
743         {
744             System.arraycopy(data, from, tmp, 0, newLength);
745         }
746 
747         return tmp;
748     }
749 
copyOfRange(BigInteger[] data, int from, int to)750     public static BigInteger[] copyOfRange(BigInteger[] data, int from, int to)
751     {
752         int newLength = getLength(from, to);
753 
754         BigInteger[] tmp = new BigInteger[newLength];
755 
756         if (data.length - from < newLength)
757         {
758             System.arraycopy(data, from, tmp, 0, data.length - from);
759         }
760         else
761         {
762             System.arraycopy(data, from, tmp, 0, newLength);
763         }
764 
765         return tmp;
766     }
767 
getLength(int from, int to)768     private static int getLength(int from, int to)
769     {
770         int newLength = to - from;
771         if (newLength < 0)
772         {
773             StringBuffer sb = new StringBuffer(from);
774             sb.append(" > ").append(to);
775             throw new IllegalArgumentException(sb.toString());
776         }
777         return newLength;
778     }
779 
append(byte[] a, byte b)780     public static byte[] append(byte[] a, byte b)
781     {
782         if (a == null)
783         {
784             return new byte[]{ b };
785         }
786 
787         int length = a.length;
788         byte[] result = new byte[length + 1];
789         System.arraycopy(a, 0, result, 0, length);
790         result[length] = b;
791         return result;
792     }
793 
append(short[] a, short b)794     public static short[] append(short[] a, short b)
795     {
796         if (a == null)
797         {
798             return new short[]{ b };
799         }
800 
801         int length = a.length;
802         short[] result = new short[length + 1];
803         System.arraycopy(a, 0, result, 0, length);
804         result[length] = b;
805         return result;
806     }
807 
append(int[] a, int b)808     public static int[] append(int[] a, int b)
809     {
810         if (a == null)
811         {
812             return new int[]{ b };
813         }
814 
815         int length = a.length;
816         int[] result = new int[length + 1];
817         System.arraycopy(a, 0, result, 0, length);
818         result[length] = b;
819         return result;
820     }
821 
concatenate(byte[] a, byte[] b)822     public static byte[] concatenate(byte[] a, byte[] b)
823     {
824         if (a != null && b != null)
825         {
826             byte[] rv = new byte[a.length + b.length];
827 
828             System.arraycopy(a, 0, rv, 0, a.length);
829             System.arraycopy(b, 0, rv, a.length, b.length);
830 
831             return rv;
832         }
833         else if (b != null)
834         {
835             return clone(b);
836         }
837         else
838         {
839             return clone(a);
840         }
841     }
842 
concatenate(byte[] a, byte[] b, byte[] c)843     public static byte[] concatenate(byte[] a, byte[] b, byte[] c)
844     {
845         if (a != null && b != null && c != null)
846         {
847             byte[] rv = new byte[a.length + b.length + c.length];
848 
849             System.arraycopy(a, 0, rv, 0, a.length);
850             System.arraycopy(b, 0, rv, a.length, b.length);
851             System.arraycopy(c, 0, rv, a.length + b.length, c.length);
852 
853             return rv;
854         }
855         else if (b == null)
856         {
857             return concatenate(a, c);
858         }
859         else
860         {
861             return concatenate(a, b);
862         }
863     }
864 
concatenate(byte[] a, byte[] b, byte[] c, byte[] d)865     public static byte[] concatenate(byte[] a, byte[] b, byte[] c, byte[] d)
866     {
867         if (a != null && b != null && c != null && d != null)
868         {
869             byte[] rv = new byte[a.length + b.length + c.length + d.length];
870 
871             System.arraycopy(a, 0, rv, 0, a.length);
872             System.arraycopy(b, 0, rv, a.length, b.length);
873             System.arraycopy(c, 0, rv, a.length + b.length, c.length);
874             System.arraycopy(d, 0, rv, a.length + b.length + c.length, d.length);
875 
876             return rv;
877         }
878         else if (d == null)
879         {
880             return concatenate(a, b, c);
881         }
882         else if (c == null)
883         {
884             return concatenate(a, b, d);
885         }
886         else if (b == null)
887         {
888             return concatenate(a, c, d);
889         }
890         else
891         {
892             return concatenate(b, c, d);
893         }
894     }
895 
concatenate(int[] a, int[] b)896     public static int[] concatenate(int[] a, int[] b)
897     {
898         if (a == null)
899         {
900             return clone(b);
901         }
902         if (b == null)
903         {
904             return clone(a);
905         }
906 
907         int[] c = new int[a.length + b.length];
908         System.arraycopy(a, 0, c, 0, a.length);
909         System.arraycopy(b, 0, c, a.length, b.length);
910         return c;
911     }
912 
prepend(byte[] a, byte b)913     public static byte[] prepend(byte[] a, byte b)
914     {
915         if (a == null)
916         {
917             return new byte[]{ b };
918         }
919 
920         int length = a.length;
921         byte[] result = new byte[length + 1];
922         System.arraycopy(a, 0, result, 1, length);
923         result[0] = b;
924         return result;
925     }
926 
prepend(short[] a, short b)927     public static short[] prepend(short[] a, short b)
928     {
929         if (a == null)
930         {
931             return new short[]{ b };
932         }
933 
934         int length = a.length;
935         short[] result = new short[length + 1];
936         System.arraycopy(a, 0, result, 1, length);
937         result[0] = b;
938         return result;
939     }
940 
prepend(int[] a, int b)941     public static int[] prepend(int[] a, int b)
942     {
943         if (a == null)
944         {
945             return new int[]{ b };
946         }
947 
948         int length = a.length;
949         int[] result = new int[length + 1];
950         System.arraycopy(a, 0, result, 1, length);
951         result[0] = b;
952         return result;
953     }
954 
reverse(byte[] a)955     public static byte[] reverse(byte[] a)
956     {
957         if (a == null)
958         {
959             return null;
960         }
961 
962         int p1 = 0, p2 = a.length;
963         byte[] result = new byte[p2];
964 
965         while (--p2 >= 0)
966         {
967             result[p2] = a[p1++];
968         }
969 
970         return result;
971     }
972 
973     /**
974      * Iterator backed by a specific array.
975      */
976     public static class Iterator<T>
977         implements java.util.Iterator<T>
978     {
979         private final T[] dataArray;
980 
981         private int position = 0;
982 
983         /**
984          * Base constructor.
985          * <p>
986          * Note: the array is not cloned, changes to it will affect the values returned by next().
987          * </p>
988          *
989          * @param dataArray array backing the iterator.
990          */
Iterator(T[] dataArray)991         public Iterator(T[] dataArray)
992         {
993             this.dataArray = dataArray;
994         }
995 
hasNext()996         public boolean hasNext()
997         {
998             return position < dataArray.length;
999         }
1000 
next()1001         public T next()
1002         {
1003             return dataArray[position++];
1004         }
1005 
remove()1006         public void remove()
1007         {
1008             throw new UnsupportedOperationException("Cannot remove element from an Array.");
1009         }
1010     }
1011 }
1012