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