Arrays.java revision bdb7b3d37025690a0434040b4e0d0623d9fa74af
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    /**
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     */
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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     */
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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         */
1070        public Iterator(T[] dataArray)
1071        {
1072            this.dataArray = dataArray;
1073        }
1074
1075        public boolean hasNext()
1076        {
1077            return position < dataArray.length;
1078        }
1079
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
1090        public void remove()
1091        {
1092            throw new UnsupportedOperationException("Cannot remove element from an Array.");
1093        }
1094    }
1095}
1096