Arrays.java revision 5db505e1f6a68c8d5dfdb0fed0b8607dea7bed96
1package org.bouncycastle.util;
2
3import java.math.BigInteger;
4
5/**
6 * General array utilities.
7 */
8public final class Arrays
9{
10    private Arrays()
11    {
12        // static class, hide constructor
13    }
14
15    public static boolean areEqual(
16        boolean[]  a,
17        boolean[]  b)
18    {
19        if (a == b)
20        {
21            return true;
22        }
23
24        if (a == null || b == null)
25        {
26            return false;
27        }
28
29        if (a.length != b.length)
30        {
31            return false;
32        }
33
34        for (int i = 0; i != a.length; i++)
35        {
36            if (a[i] != b[i])
37            {
38                return false;
39            }
40        }
41
42        return true;
43    }
44
45    public static boolean areEqual(
46        char[]  a,
47        char[]  b)
48    {
49        if (a == b)
50        {
51            return true;
52        }
53
54        if (a == null || b == null)
55        {
56            return false;
57        }
58
59        if (a.length != b.length)
60        {
61            return false;
62        }
63
64        for (int i = 0; i != a.length; i++)
65        {
66            if (a[i] != b[i])
67            {
68                return false;
69            }
70        }
71
72        return true;
73    }
74
75    public static boolean areEqual(
76        byte[]  a,
77        byte[]  b)
78    {
79        if (a == b)
80        {
81            return true;
82        }
83
84        if (a == null || b == null)
85        {
86            return false;
87        }
88
89        if (a.length != b.length)
90        {
91            return false;
92        }
93
94        for (int i = 0; i != a.length; i++)
95        {
96            if (a[i] != b[i])
97            {
98                return false;
99            }
100        }
101
102        return true;
103    }
104
105    /**
106     * A constant time equals comparison - does not terminate early if
107     * test will fail.
108     *
109     * @param a first array
110     * @param b second array
111     * @return true if arrays equal, false otherwise.
112     */
113    public static boolean constantTimeAreEqual(
114        byte[]  a,
115        byte[]  b)
116    {
117        if (a == b)
118        {
119            return true;
120        }
121
122        if (a == null || b == null)
123        {
124            return false;
125        }
126
127        if (a.length != b.length)
128        {
129            return false;
130        }
131
132        int nonEqual = 0;
133
134        for (int i = 0; i != a.length; i++)
135        {
136            nonEqual |= (a[i] ^ b[i]);
137        }
138
139        return nonEqual == 0;
140    }
141
142    public static boolean areEqual(
143        int[]  a,
144        int[]  b)
145    {
146        if (a == b)
147        {
148            return true;
149        }
150
151        if (a == null || b == null)
152        {
153            return false;
154        }
155
156        if (a.length != b.length)
157        {
158            return false;
159        }
160
161        for (int i = 0; i != a.length; i++)
162        {
163            if (a[i] != b[i])
164            {
165                return false;
166            }
167        }
168
169        return true;
170    }
171
172    public static boolean areEqual(
173        long[]  a,
174        long[]  b)
175    {
176        if (a == b)
177        {
178            return true;
179        }
180
181        if (a == null || b == null)
182        {
183            return false;
184        }
185
186        if (a.length != b.length)
187        {
188            return false;
189        }
190
191        for (int i = 0; i != a.length; i++)
192        {
193            if (a[i] != b[i])
194            {
195                return false;
196            }
197        }
198
199        return true;
200    }
201
202    public static boolean areEqual(Object[] a, Object[] b)
203    {
204        if (a == b)
205        {
206            return true;
207        }
208        if (a == null || b == null)
209        {
210            return false;
211        }
212        if (a.length != b.length)
213        {
214            return false;
215        }
216        for (int i = 0; i != a.length; i++)
217        {
218            Object objA = a[i], objB = b[i];
219            if (objA == null)
220            {
221                if (objB != null)
222                {
223                    return false;
224                }
225            }
226            else if (!objA.equals(objB))
227            {
228                return false;
229            }
230        }
231        return true;
232    }
233
234    public static boolean contains(short[] a, short n)
235    {
236        for (int i = 0; i < a.length; ++i)
237        {
238            if (a[i] == n)
239            {
240                return true;
241            }
242        }
243        return false;
244    }
245
246    public static boolean contains(int[] a, int n)
247    {
248        for (int i = 0; i < a.length; ++i)
249        {
250            if (a[i] == n)
251            {
252                return true;
253            }
254        }
255        return false;
256    }
257
258    public static void fill(
259        byte[] array,
260        byte value)
261    {
262        for (int i = 0; i < array.length; i++)
263        {
264            array[i] = value;
265        }
266    }
267
268    public static void fill(
269        char[] array,
270        char value)
271    {
272        for (int i = 0; i < array.length; i++)
273        {
274            array[i] = value;
275        }
276    }
277
278    public static void fill(
279        long[] array,
280        long value)
281    {
282        for (int i = 0; i < array.length; i++)
283        {
284            array[i] = value;
285        }
286    }
287
288    public static void fill(
289        short[] array,
290        short value)
291    {
292        for (int i = 0; i < array.length; i++)
293        {
294            array[i] = value;
295        }
296    }
297
298    public static void fill(
299        int[] array,
300        int value)
301    {
302        for (int i = 0; i < array.length; i++)
303        {
304            array[i] = value;
305        }
306    }
307
308    public static int hashCode(byte[] data)
309    {
310        if (data == null)
311        {
312            return 0;
313        }
314
315        int i = data.length;
316        int hc = i + 1;
317
318        while (--i >= 0)
319        {
320            hc *= 257;
321            hc ^= data[i];
322        }
323
324        return hc;
325    }
326
327    public static int hashCode(char[] data)
328    {
329        if (data == null)
330        {
331            return 0;
332        }
333
334        int i = data.length;
335        int hc = i + 1;
336
337        while (--i >= 0)
338        {
339            hc *= 257;
340            hc ^= data[i];
341        }
342
343        return hc;
344    }
345
346    public static int hashCode(int[][] ints)
347    {
348        int hc = 0;
349
350        for (int i = 0; i != ints.length; i++)
351        {
352            hc = hc * 257 + hashCode(ints[i]);
353        }
354
355        return hc;
356    }
357
358    public static int hashCode(int[] data)
359    {
360        if (data == null)
361        {
362            return 0;
363        }
364
365        int i = data.length;
366        int hc = i + 1;
367
368        while (--i >= 0)
369        {
370            hc *= 257;
371            hc ^= data[i];
372        }
373
374        return hc;
375    }
376
377    public static int hashCode(short[][][] shorts)
378    {
379        int hc = 0;
380
381        for (int i = 0; i != shorts.length; i++)
382        {
383            hc = hc * 257 + hashCode(shorts[i]);
384        }
385
386        return hc;
387    }
388
389    public static int hashCode(short[][] shorts)
390    {
391        int hc = 0;
392
393        for (int i = 0; i != shorts.length; i++)
394        {
395            hc = hc * 257 + hashCode(shorts[i]);
396        }
397
398        return hc;
399    }
400
401    public static int hashCode(short[] data)
402    {
403        if (data == null)
404        {
405            return 0;
406        }
407
408        int i = data.length;
409        int hc = i + 1;
410
411        while (--i >= 0)
412        {
413            hc *= 257;
414            hc ^= (data[i] & 0xff);
415        }
416
417        return hc;
418    }
419
420    public static int hashCode(Object[] data)
421    {
422        if (data == null)
423        {
424            return 0;
425        }
426
427        int i = data.length;
428        int hc = i + 1;
429
430        while (--i >= 0)
431        {
432            hc *= 257;
433            hc ^= data[i].hashCode();
434        }
435
436        return hc;
437    }
438
439    public static byte[] clone(byte[] data)
440    {
441        if (data == null)
442        {
443            return null;
444        }
445        byte[] copy = new byte[data.length];
446
447        System.arraycopy(data, 0, copy, 0, data.length);
448
449        return copy;
450    }
451
452    public static byte[] clone(byte[] data, byte[] existing)
453    {
454        if (data == null)
455        {
456            return null;
457        }
458        if ((existing == null) || (existing.length != data.length))
459        {
460            return clone(data);
461        }
462        System.arraycopy(data, 0, existing, 0, existing.length);
463        return existing;
464    }
465
466    public static byte[][] clone(byte[][] data)
467    {
468        if (data == null)
469        {
470            return null;
471        }
472
473        byte[][] copy = new byte[data.length][];
474
475        for (int i = 0; i != copy.length; i++)
476        {
477            copy[i] = clone(data[i]);
478        }
479
480        return copy;
481    }
482
483    public static byte[][][] clone(byte[][][] data)
484    {
485        if (data == null)
486        {
487            return null;
488        }
489
490        byte[][][] copy = new byte[data.length][][];
491
492        for (int i = 0; i != copy.length; i++)
493        {
494            copy[i] = clone(data[i]);
495        }
496
497        return copy;
498    }
499
500    public static int[] clone(int[] data)
501    {
502        if (data == null)
503        {
504            return null;
505        }
506        int[] copy = new int[data.length];
507
508        System.arraycopy(data, 0, copy, 0, data.length);
509
510        return copy;
511    }
512
513    public static long[] clone(long[] data)
514    {
515        if (data == null)
516        {
517            return null;
518        }
519        long[] copy = new long[data.length];
520
521        System.arraycopy(data, 0, copy, 0, data.length);
522
523        return copy;
524    }
525
526    public static long[] clone(long[] data, long[] existing)
527    {
528        if (data == null)
529        {
530            return null;
531        }
532        if ((existing == null) || (existing.length != data.length))
533        {
534            return clone(data);
535        }
536        System.arraycopy(data, 0, existing, 0, existing.length);
537        return existing;
538    }
539
540    public static short[] clone(short[] data)
541    {
542        if (data == null)
543        {
544            return null;
545        }
546        short[] copy = new short[data.length];
547
548        System.arraycopy(data, 0, copy, 0, data.length);
549
550        return copy;
551    }
552
553    public static BigInteger[] clone(BigInteger[] data)
554    {
555        if (data == null)
556        {
557            return null;
558        }
559        BigInteger[] copy = new BigInteger[data.length];
560
561        System.arraycopy(data, 0, copy, 0, data.length);
562
563        return copy;
564    }
565
566    public static byte[] copyOf(byte[] data, int newLength)
567    {
568        byte[] tmp = new byte[newLength];
569
570        if (newLength < data.length)
571        {
572            System.arraycopy(data, 0, tmp, 0, newLength);
573        }
574        else
575        {
576            System.arraycopy(data, 0, tmp, 0, data.length);
577        }
578
579        return tmp;
580    }
581
582    public static char[] copyOf(char[] data, int newLength)
583    {
584        char[] tmp = new char[newLength];
585
586        if (newLength < data.length)
587        {
588            System.arraycopy(data, 0, tmp, 0, newLength);
589        }
590        else
591        {
592            System.arraycopy(data, 0, tmp, 0, data.length);
593        }
594
595        return tmp;
596    }
597
598    public static int[] copyOf(int[] data, int newLength)
599    {
600        int[] tmp = new int[newLength];
601
602        if (newLength < data.length)
603        {
604            System.arraycopy(data, 0, tmp, 0, newLength);
605        }
606        else
607        {
608            System.arraycopy(data, 0, tmp, 0, data.length);
609        }
610
611        return tmp;
612    }
613
614    public static long[] copyOf(long[] data, int newLength)
615    {
616        long[] tmp = new long[newLength];
617
618        if (newLength < data.length)
619        {
620            System.arraycopy(data, 0, tmp, 0, newLength);
621        }
622        else
623        {
624            System.arraycopy(data, 0, tmp, 0, data.length);
625        }
626
627        return tmp;
628    }
629
630    public static BigInteger[] copyOf(BigInteger[] data, int newLength)
631    {
632        BigInteger[] tmp = new BigInteger[newLength];
633
634        if (newLength < data.length)
635        {
636            System.arraycopy(data, 0, tmp, 0, newLength);
637        }
638        else
639        {
640            System.arraycopy(data, 0, tmp, 0, data.length);
641        }
642
643        return tmp;
644    }
645
646    /**
647     * Make a copy of a range of bytes from the passed in data array. The range can
648     * extend beyond the end of the input array, in which case the return array will
649     * be padded with zeroes.
650     *
651     * @param data the array from which the data is to be copied.
652     * @param from the start index at which the copying should take place.
653     * @param to the final index of the range (exclusive).
654     *
655     * @return a new byte array containing the range given.
656     */
657    public static byte[] copyOfRange(byte[] data, int from, int to)
658    {
659        int newLength = getLength(from, to);
660
661        byte[] tmp = new byte[newLength];
662
663        if (data.length - from < newLength)
664        {
665            System.arraycopy(data, from, tmp, 0, data.length - from);
666        }
667        else
668        {
669            System.arraycopy(data, from, tmp, 0, newLength);
670        }
671
672        return tmp;
673    }
674
675    public static int[] copyOfRange(int[] data, int from, int to)
676    {
677        int newLength = getLength(from, to);
678
679        int[] tmp = new int[newLength];
680
681        if (data.length - from < newLength)
682        {
683            System.arraycopy(data, from, tmp, 0, data.length - from);
684        }
685        else
686        {
687            System.arraycopy(data, from, tmp, 0, newLength);
688        }
689
690        return tmp;
691    }
692
693    public static long[] copyOfRange(long[] data, int from, int to)
694    {
695        int newLength = getLength(from, to);
696
697        long[] tmp = new long[newLength];
698
699        if (data.length - from < newLength)
700        {
701            System.arraycopy(data, from, tmp, 0, data.length - from);
702        }
703        else
704        {
705            System.arraycopy(data, from, tmp, 0, newLength);
706        }
707
708        return tmp;
709    }
710
711    public static BigInteger[] copyOfRange(BigInteger[] data, int from, int to)
712    {
713        int newLength = getLength(from, to);
714
715        BigInteger[] tmp = new BigInteger[newLength];
716
717        if (data.length - from < newLength)
718        {
719            System.arraycopy(data, from, tmp, 0, data.length - from);
720        }
721        else
722        {
723            System.arraycopy(data, from, tmp, 0, newLength);
724        }
725
726        return tmp;
727    }
728
729    private static int getLength(int from, int to)
730    {
731        int newLength = to - from;
732        if (newLength < 0)
733        {
734            StringBuffer sb = new StringBuffer(from);
735            sb.append(" > ").append(to);
736            throw new IllegalArgumentException(sb.toString());
737        }
738        return newLength;
739    }
740
741    public static byte[] append(byte[] a, byte b)
742    {
743        if (a == null)
744        {
745            return new byte[]{ b };
746        }
747
748        int length = a.length;
749        byte[] result = new byte[length + 1];
750        System.arraycopy(a, 0, result, 0, length);
751        result[length] = b;
752        return result;
753    }
754
755    public static int[] append(int[] a, int b)
756    {
757        if (a == null)
758        {
759            return new int[]{ b };
760        }
761
762        int length = a.length;
763        int[] result = new int[length + 1];
764        System.arraycopy(a, 0, result, 0, length);
765        result[length] = b;
766        return result;
767    }
768
769    public static byte[] concatenate(byte[] a, byte[] b)
770    {
771        if (a != null && b != null)
772        {
773            byte[] rv = new byte[a.length + b.length];
774
775            System.arraycopy(a, 0, rv, 0, a.length);
776            System.arraycopy(b, 0, rv, a.length, b.length);
777
778            return rv;
779        }
780        else if (b != null)
781        {
782            return clone(b);
783        }
784        else
785        {
786            return clone(a);
787        }
788    }
789
790    public static byte[] concatenate(byte[] a, byte[] b, byte[] c)
791    {
792        if (a != null && b != null && c != null)
793        {
794            byte[] rv = new byte[a.length + b.length + c.length];
795
796            System.arraycopy(a, 0, rv, 0, a.length);
797            System.arraycopy(b, 0, rv, a.length, b.length);
798            System.arraycopy(c, 0, rv, a.length + b.length, c.length);
799
800            return rv;
801        }
802        else if (b == null)
803        {
804            return concatenate(a, c);
805        }
806        else
807        {
808            return concatenate(a, b);
809        }
810    }
811
812    public static byte[] concatenate(byte[] a, byte[] b, byte[] c, byte[] d)
813    {
814        if (a != null && b != null && c != null && d != null)
815        {
816            byte[] rv = new byte[a.length + b.length + c.length + d.length];
817
818            System.arraycopy(a, 0, rv, 0, a.length);
819            System.arraycopy(b, 0, rv, a.length, b.length);
820            System.arraycopy(c, 0, rv, a.length + b.length, c.length);
821            System.arraycopy(d, 0, rv, a.length + b.length + c.length, d.length);
822
823            return rv;
824        }
825        else if (d == null)
826        {
827            return concatenate(a, b, c);
828        }
829        else if (c == null)
830        {
831            return concatenate(a, b, d);
832        }
833        else if (b == null)
834        {
835            return concatenate(a, c, d);
836        }
837        else
838        {
839            return concatenate(b, c, d);
840        }
841    }
842
843    public static byte[] prepend(byte[] a, byte b)
844    {
845        if (a == null)
846        {
847            return new byte[]{ b };
848        }
849
850        int length = a.length;
851        byte[] result = new byte[length + 1];
852        System.arraycopy(a, 0, result, 1, length);
853        result[0] = b;
854        return result;
855    }
856}
857