1 package org.bouncycastle.util; 2 3 import java.math.BigInteger; 4 import java.util.NoSuchElementException; 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(long[] data)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 hashCode(long[] data, int off, int len)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 hashCode(short[][][] shorts)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 hashCode(short[][] shorts)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 hashCode(short[] data)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 hashCode(Object[] data)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 clone(byte[] data)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 clone(char[] data)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 clone(byte[] data, byte[] existing)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 clone(byte[][] data)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 clone(byte[][][] data)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 clone(int[] data)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 clone(long[] data)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 clone(long[] data, long[] existing)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 clone(short[] data)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 clone(BigInteger[] data)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 copyOf(byte[] data, int newLength)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 copyOf(char[] data, int newLength)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 copyOf(int[] data, int newLength)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 copyOf(long[] data, int newLength)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 copyOf(BigInteger[] data, int newLength)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 */ copyOfRange(byte[] data, int from, int to)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 copyOfRange(int[] data, int from, int to)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 copyOfRange(long[] data, int from, int to)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 copyOfRange(BigInteger[] data, int from, int to)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 getLength(int from, int to)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 append(byte[] a, byte b)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 append(short[] a, short b)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 append(int[] a, int b)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 concatenate(byte[] a, byte[] b)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 concatenate(byte[] a, byte[] b, byte[] c)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 concatenate(byte[] a, byte[] b, byte[] c, byte[] d)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 concatenate(int[] a, int[] b)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 prepend(byte[] a, byte b)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 prepend(short[] a, short b)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 prepend(int[] a, int b)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 reverse(byte[] a)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 reverse(int[] a)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 */ Iterator(T[] dataArray)1070 public Iterator(T[] dataArray) 1071 { 1072 this.dataArray = dataArray; 1073 } 1074 hasNext()1075 public boolean hasNext() 1076 { 1077 return position < dataArray.length; 1078 } 1079 next()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 remove()1090 public void remove() 1091 { 1092 throw new UnsupportedOperationException("Cannot remove element from an Array."); 1093 } 1094 } 1095 } 1096