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