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(
203        BigInteger[]  a,
204        BigInteger[]  b)
205    {
206        if (a == b)
207        {
208            return true;
209        }
210
211        if (a == null || b == null)
212        {
213            return false;
214        }
215
216        if (a.length != b.length)
217        {
218            return false;
219        }
220
221        for (int i = 0; i != a.length; i++)
222        {
223            if (!a[i].equals(b[i]))
224            {
225                return false;
226            }
227        }
228
229        return true;
230    }
231
232    public static void fill(
233        byte[] array,
234        byte value)
235    {
236        for (int i = 0; i < array.length; i++)
237        {
238            array[i] = value;
239        }
240    }
241
242    public static void fill(
243        char[] array,
244        char value)
245    {
246        for (int i = 0; i < array.length; i++)
247        {
248            array[i] = value;
249        }
250    }
251
252    public static void fill(
253        long[] array,
254        long value)
255    {
256        for (int i = 0; i < array.length; i++)
257        {
258            array[i] = value;
259        }
260    }
261
262    public static void fill(
263        short[] array,
264        short value)
265    {
266        for (int i = 0; i < array.length; i++)
267        {
268            array[i] = value;
269        }
270    }
271
272    public static void fill(
273        int[] array,
274        int value)
275    {
276        for (int i = 0; i < array.length; i++)
277        {
278            array[i] = value;
279        }
280    }
281
282    public static int hashCode(byte[] data)
283    {
284        if (data == null)
285        {
286            return 0;
287        }
288
289        int i = data.length;
290        int hc = i + 1;
291
292        while (--i >= 0)
293        {
294            hc *= 257;
295            hc ^= data[i];
296        }
297
298        return hc;
299    }
300
301    public static int hashCode(char[] data)
302    {
303        if (data == null)
304        {
305            return 0;
306        }
307
308        int i = data.length;
309        int hc = i + 1;
310
311        while (--i >= 0)
312        {
313            hc *= 257;
314            hc ^= data[i];
315        }
316
317        return hc;
318    }
319
320    public static int hashCode(int[][] ints)
321    {
322        int hc = 0;
323
324        for (int i = 0; i != ints.length; i++)
325        {
326            hc = hc * 257 + hashCode(ints[i]);
327        }
328
329        return hc;
330    }
331
332    public static int hashCode(int[] data)
333    {
334        if (data == null)
335        {
336            return 0;
337        }
338
339        int i = data.length;
340        int hc = i + 1;
341
342        while (--i >= 0)
343        {
344            hc *= 257;
345            hc ^= data[i];
346        }
347
348        return hc;
349    }
350
351    public static int hashCode(short[][][] shorts)
352    {
353        int hc = 0;
354
355        for (int i = 0; i != shorts.length; i++)
356        {
357            hc = hc * 257 + hashCode(shorts[i]);
358        }
359
360        return hc;
361    }
362
363    public static int hashCode(short[][] shorts)
364    {
365        int hc = 0;
366
367        for (int i = 0; i != shorts.length; i++)
368        {
369            hc = hc * 257 + hashCode(shorts[i]);
370        }
371
372        return hc;
373    }
374
375    public static int hashCode(short[] data)
376    {
377        if (data == null)
378        {
379            return 0;
380        }
381
382        int i = data.length;
383        int hc = i + 1;
384
385        while (--i >= 0)
386        {
387            hc *= 257;
388            hc ^= (data[i] & 0xff);
389        }
390
391        return hc;
392    }
393
394    public static int hashCode(BigInteger[] data)
395    {
396        if (data == null)
397        {
398            return 0;
399        }
400
401        int i = data.length;
402        int hc = i + 1;
403
404        while (--i >= 0)
405        {
406            hc *= 257;
407            hc ^= data[i].hashCode();
408        }
409
410        return hc;
411    }
412
413    public static byte[] clone(byte[] data)
414    {
415        if (data == null)
416        {
417            return null;
418        }
419        byte[] copy = new byte[data.length];
420
421        System.arraycopy(data, 0, copy, 0, data.length);
422
423        return copy;
424    }
425
426    public static byte[][] clone(byte[][] data)
427    {
428        if (data == null)
429        {
430            return null;
431        }
432
433        byte[][] copy = new byte[data.length][];
434
435        for (int i = 0; i != copy.length; i++)
436        {
437            copy[i] = clone(data[i]);
438        }
439
440        return copy;
441    }
442
443    public static byte[][][] clone(byte[][][] data)
444    {
445        if (data == null)
446        {
447            return null;
448        }
449
450        byte[][][] copy = new byte[data.length][][];
451
452        for (int i = 0; i != copy.length; i++)
453        {
454            copy[i] = clone(data[i]);
455        }
456
457        return copy;
458    }
459
460    public static int[] clone(int[] data)
461    {
462        if (data == null)
463        {
464            return null;
465        }
466        int[] copy = new int[data.length];
467
468        System.arraycopy(data, 0, copy, 0, data.length);
469
470        return copy;
471    }
472
473    public static short[] clone(short[] data)
474    {
475        if (data == null)
476        {
477            return null;
478        }
479        short[] copy = new short[data.length];
480
481        System.arraycopy(data, 0, copy, 0, data.length);
482
483        return copy;
484    }
485
486    public static BigInteger[] clone(BigInteger[] data)
487    {
488        if (data == null)
489        {
490            return null;
491        }
492        BigInteger[] copy = new BigInteger[data.length];
493
494        System.arraycopy(data, 0, copy, 0, data.length);
495
496        return copy;
497    }
498
499    public static byte[] copyOf(byte[] data, int newLength)
500    {
501        byte[] tmp = new byte[newLength];
502
503        if (newLength < data.length)
504        {
505            System.arraycopy(data, 0, tmp, 0, newLength);
506        }
507        else
508        {
509            System.arraycopy(data, 0, tmp, 0, data.length);
510        }
511
512        return tmp;
513    }
514
515    public static char[] copyOf(char[] data, int newLength)
516    {
517        char[] tmp = new char[newLength];
518
519        if (newLength < data.length)
520        {
521            System.arraycopy(data, 0, tmp, 0, newLength);
522        }
523        else
524        {
525            System.arraycopy(data, 0, tmp, 0, data.length);
526        }
527
528        return tmp;
529    }
530
531    public static int[] copyOf(int[] data, int newLength)
532    {
533        int[] tmp = new int[newLength];
534
535        if (newLength < data.length)
536        {
537            System.arraycopy(data, 0, tmp, 0, newLength);
538        }
539        else
540        {
541            System.arraycopy(data, 0, tmp, 0, data.length);
542        }
543
544        return tmp;
545    }
546
547    public static long[] copyOf(long[] data, int newLength)
548    {
549        long[] tmp = new long[newLength];
550
551        if (newLength < data.length)
552        {
553            System.arraycopy(data, 0, tmp, 0, newLength);
554        }
555        else
556        {
557            System.arraycopy(data, 0, tmp, 0, data.length);
558        }
559
560        return tmp;
561    }
562
563    public static BigInteger[] copyOf(BigInteger[] data, int newLength)
564    {
565        BigInteger[] tmp = new BigInteger[newLength];
566
567        if (newLength < data.length)
568        {
569            System.arraycopy(data, 0, tmp, 0, newLength);
570        }
571        else
572        {
573            System.arraycopy(data, 0, tmp, 0, data.length);
574        }
575
576        return tmp;
577    }
578
579    public static byte[] copyOfRange(byte[] data, int from, int to)
580    {
581        int newLength = getLength(from, to);
582
583        byte[] tmp = new byte[newLength];
584
585        if (data.length - from < newLength)
586        {
587            System.arraycopy(data, from, tmp, 0, data.length - from);
588        }
589        else
590        {
591            System.arraycopy(data, from, tmp, 0, newLength);
592        }
593
594        return tmp;
595    }
596
597    public static int[] copyOfRange(int[] data, int from, int to)
598    {
599        int newLength = getLength(from, to);
600
601        int[] tmp = new int[newLength];
602
603        if (data.length - from < newLength)
604        {
605            System.arraycopy(data, from, tmp, 0, data.length - from);
606        }
607        else
608        {
609            System.arraycopy(data, from, tmp, 0, newLength);
610        }
611
612        return tmp;
613    }
614
615    public static long[] copyOfRange(long[] data, int from, int to)
616    {
617        int newLength = getLength(from, to);
618
619        long[] tmp = new long[newLength];
620
621        if (data.length - from < newLength)
622        {
623            System.arraycopy(data, from, tmp, 0, data.length - from);
624        }
625        else
626        {
627            System.arraycopy(data, from, tmp, 0, newLength);
628        }
629
630        return tmp;
631    }
632
633    public static BigInteger[] copyOfRange(BigInteger[] data, int from, int to)
634    {
635        int newLength = getLength(from, to);
636
637        BigInteger[] tmp = new BigInteger[newLength];
638
639        if (data.length - from < newLength)
640        {
641            System.arraycopy(data, from, tmp, 0, data.length - from);
642        }
643        else
644        {
645            System.arraycopy(data, from, tmp, 0, newLength);
646        }
647
648        return tmp;
649    }
650
651    private static int getLength(int from, int to)
652    {
653        int newLength = to - from;
654        if (newLength < 0)
655        {
656            StringBuffer sb = new StringBuffer(from);
657            sb.append(" > ").append(to);
658            throw new IllegalArgumentException(sb.toString());
659        }
660        return newLength;
661    }
662
663    public static byte[] concatenate(byte[] a, byte[] b)
664    {
665        if (a != null && b != null)
666        {
667            byte[] rv = new byte[a.length + b.length];
668
669            System.arraycopy(a, 0, rv, 0, a.length);
670            System.arraycopy(b, 0, rv, a.length, b.length);
671
672            return rv;
673        }
674        else if (b != null)
675        {
676            return clone(b);
677        }
678        else
679        {
680            return clone(a);
681        }
682    }
683
684    public static byte[] concatenate(byte[] a, byte[] b, byte[] c)
685    {
686        if (a != null && b != null && c != null)
687        {
688            byte[] rv = new byte[a.length + b.length + c.length];
689
690            System.arraycopy(a, 0, rv, 0, a.length);
691            System.arraycopy(b, 0, rv, a.length, b.length);
692            System.arraycopy(c, 0, rv, a.length + b.length, c.length);
693
694            return rv;
695        }
696        else if (b == null)
697        {
698            return concatenate(a, c);
699        }
700        else
701        {
702            return concatenate(a, b);
703        }
704    }
705
706    public static byte[] concatenate(byte[] a, byte[] b, byte[] c, byte[] d)
707    {
708        if (a != null && b != null && c != null && d != null)
709        {
710            byte[] rv = new byte[a.length + b.length + c.length + d.length];
711
712            System.arraycopy(a, 0, rv, 0, a.length);
713            System.arraycopy(b, 0, rv, a.length, b.length);
714            System.arraycopy(c, 0, rv, a.length + b.length, c.length);
715            System.arraycopy(d, 0, rv, a.length + b.length + c.length, d.length);
716
717            return rv;
718        }
719        else if (d == null)
720        {
721            return concatenate(a, b, c);
722        }
723        else if (c == null)
724        {
725            return concatenate(a, b, d);
726        }
727        else if (b == null)
728        {
729            return concatenate(a, c, d);
730        }
731        else
732        {
733            return concatenate(b, c, d);
734        }
735    }
736}
737