Complex classes like BigInteger often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use BigInteger, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 14 | class BigInteger |
||
| 15 | { |
||
| 16 | const MONTGOMERY = 0; |
||
| 17 | |||
| 18 | const BARRETT = 1; |
||
| 19 | |||
| 20 | const POWEROF2 = 2; |
||
| 21 | |||
| 22 | const CLASSIC = 3; |
||
| 23 | |||
| 24 | const NONE = 4; |
||
| 25 | |||
| 26 | /**#@+ |
||
| 27 | * Array constants |
||
| 28 | * |
||
| 29 | * Rather than create a thousands and thousands of new BigInteger objects in repeated function calls to add() and |
||
| 30 | * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them. |
||
| 31 | * |
||
| 32 | */ |
||
| 33 | /** |
||
| 34 | * $result[self::VALUE] contains the value. |
||
| 35 | */ |
||
| 36 | const VALUE = 0; |
||
| 37 | /** |
||
| 38 | * $result[self::SIGN] contains the sign. |
||
| 39 | */ |
||
| 40 | const SIGN = 1; |
||
| 41 | /**#@-*/ |
||
| 42 | |||
| 43 | /**#@+ |
||
| 44 | */ |
||
| 45 | /** |
||
| 46 | * Cache constants. |
||
| 47 | * |
||
| 48 | * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. |
||
| 49 | */ |
||
| 50 | const VARIABLE = 0; |
||
| 51 | /** |
||
| 52 | * $cache[self::DATA] contains the cached data. |
||
| 53 | */ |
||
| 54 | const DATA = 1; |
||
| 55 | /**#@-*/ |
||
| 56 | |||
| 57 | /** |
||
| 58 | * Karatsuba Cutoff. |
||
| 59 | * |
||
| 60 | * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication? |
||
| 61 | */ |
||
| 62 | const KARATSUBA_CUTOFF = 25; |
||
| 63 | |||
| 64 | /**#@+ |
||
| 65 | * Static properties used by the pure-PHP implementation. |
||
| 66 | * |
||
| 67 | * @see __construct() |
||
| 68 | */ |
||
| 69 | protected static $base; |
||
| 70 | protected static $baseFull; |
||
| 71 | protected static $maxDigit; |
||
| 72 | protected static $msb; |
||
| 73 | |||
| 74 | /** |
||
| 75 | * $max10 in greatest $max10Len satisfying |
||
| 76 | * $max10 = 10**$max10Len <= 2**$base. |
||
| 77 | */ |
||
| 78 | protected static $max10; |
||
| 79 | |||
| 80 | /** |
||
| 81 | * $max10Len in greatest $max10Len satisfying |
||
| 82 | * $max10 = 10**$max10Len <= 2**$base. |
||
| 83 | */ |
||
| 84 | protected static $max10Len; |
||
| 85 | protected static $maxDigit2; |
||
| 86 | /**#@-*/ |
||
| 87 | |||
| 88 | /** |
||
| 89 | * Holds the BigInteger's value. |
||
| 90 | * |
||
| 91 | * @var array |
||
| 92 | */ |
||
| 93 | private $value; |
||
| 94 | |||
| 95 | /** |
||
| 96 | * Holds the BigInteger's magnitude. |
||
| 97 | * |
||
| 98 | * @var bool |
||
| 99 | */ |
||
| 100 | private $is_negative = false; |
||
| 101 | |||
| 102 | /** |
||
| 103 | * Precision. |
||
| 104 | */ |
||
| 105 | private $precision = -1; |
||
| 106 | |||
| 107 | /** |
||
| 108 | * Precision Bitmask. |
||
| 109 | */ |
||
| 110 | private $bitmask = false; |
||
| 111 | |||
| 112 | /** |
||
| 113 | * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers. |
||
| 114 | * |
||
| 115 | * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using |
||
| 116 | * two's compliment. The sole exception to this is -10, which is treated the same as 10 is. |
||
| 117 | * |
||
| 118 | * Here's an example: |
||
| 119 | * <code> |
||
| 120 | * <?php |
||
| 121 | * $a = new \Jose\Util\in base-16 |
||
| 122 | * |
||
| 123 | * echo $a->toString(); // outputs 50 |
||
| 124 | * ?> |
||
| 125 | * </code> |
||
| 126 | * |
||
| 127 | * @param $x base-10 number or base-$base number if $base set. |
||
| 128 | * @param int $base |
||
| 129 | * |
||
| 130 | * @return \Jose\Util\BigInteger |
||
|
|
|||
| 131 | */ |
||
| 132 | public function __construct($x = 0, $base = 10) |
||
| 233 | |||
| 234 | /** |
||
| 235 | * Converts a BigInteger to a byte string (eg. base-256). |
||
| 236 | * |
||
| 237 | * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're |
||
| 238 | * saved as two's compliment. |
||
| 239 | * |
||
| 240 | * Here's an example: |
||
| 241 | * <code> |
||
| 242 | * <?php |
||
| 243 | * $a = new \Jose\Util\ger('65'); |
||
| 244 | * |
||
| 245 | * echo $a->toBytes(); // outputs chr(65) |
||
| 246 | * ?> |
||
| 247 | * </code> |
||
| 248 | * |
||
| 249 | * @param bool $twos_compliment |
||
| 250 | * |
||
| 251 | * @return string |
||
| 252 | * |
||
| 253 | */ |
||
| 254 | public function toBytes($twos_compliment = false) |
||
| 288 | |||
| 289 | /** |
||
| 290 | * Converts a BigInteger to a hex string (eg. base-16)). |
||
| 291 | * |
||
| 292 | * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're |
||
| 293 | * saved as two's compliment. |
||
| 294 | * |
||
| 295 | * Here's an example: |
||
| 296 | * <code> |
||
| 297 | * <?php |
||
| 298 | * $a = new \Jose\Util\ger('65'); |
||
| 299 | * |
||
| 300 | * echo $a->toHex(); // outputs '41' |
||
| 301 | * ?> |
||
| 302 | * </code> |
||
| 303 | * |
||
| 304 | * @param bool $twos_compliment |
||
| 305 | * |
||
| 306 | * @return string |
||
| 307 | * |
||
| 308 | */ |
||
| 309 | public function toHex($twos_compliment = false) |
||
| 313 | |||
| 314 | /** |
||
| 315 | * Converts a BigInteger to a bit string (eg. base-2). |
||
| 316 | * |
||
| 317 | * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're |
||
| 318 | * saved as two's compliment. |
||
| 319 | * |
||
| 320 | * Here's an example: |
||
| 321 | * <code> |
||
| 322 | * <?php |
||
| 323 | * $a = new \Jose\Util\ger('65'); |
||
| 324 | * |
||
| 325 | * echo $a->toBits(); // outputs '1000001' |
||
| 326 | * ?> |
||
| 327 | * </code> |
||
| 328 | * |
||
| 329 | * @param bool $twos_compliment |
||
| 330 | * |
||
| 331 | * @return string |
||
| 332 | * |
||
| 333 | */ |
||
| 334 | public function toBits($twos_compliment = false) |
||
| 352 | |||
| 353 | /** |
||
| 354 | * Adds two BigIntegers. |
||
| 355 | * |
||
| 356 | * Here's an example: |
||
| 357 | * <code> |
||
| 358 | * <?php |
||
| 359 | * $a = new \Jose\Util\ger('10'); |
||
| 360 | * $b = new \Jose\Util\ger('20'); |
||
| 361 | * |
||
| 362 | * $c = $a->add($b); |
||
| 363 | * |
||
| 364 | * echo $c->toString(); // outputs 30 |
||
| 365 | * ?> |
||
| 366 | * </code> |
||
| 367 | * |
||
| 368 | * @param \Jose\Util\Integer $y |
||
| 369 | * |
||
| 370 | * @return \Jose\Util\BigInteger |
||
| 371 | * |
||
| 372 | */ |
||
| 373 | public function add(BigInteger $y) |
||
| 380 | |||
| 381 | /** |
||
| 382 | * Performs addition. |
||
| 383 | * |
||
| 384 | * @param array $x_value |
||
| 385 | * @param bool $x_negative |
||
| 386 | * @param array $y_value |
||
| 387 | * @param bool $y_negative |
||
| 388 | * |
||
| 389 | * @return array |
||
| 390 | */ |
||
| 391 | private static function _add($x_value, $x_negative, $y_value, $y_negative) |
||
| 465 | |||
| 466 | /** |
||
| 467 | * Subtracts two BigIntegers. |
||
| 468 | * |
||
| 469 | * Here's an example: |
||
| 470 | * <code> |
||
| 471 | * <?php |
||
| 472 | * $a = new \Jose\Util\ger('10'); |
||
| 473 | * $b = new \Jose\Util\ger('20'); |
||
| 474 | * |
||
| 475 | * $c = $a->subtract($b); |
||
| 476 | * |
||
| 477 | * echo $c->toString(); // outputs -10 |
||
| 478 | * ?> |
||
| 479 | * </code> |
||
| 480 | * |
||
| 481 | * @param \Jose\Util\Integer $y |
||
| 482 | * |
||
| 483 | * @return \Jose\Util\BigInteger |
||
| 484 | * |
||
| 485 | */ |
||
| 486 | public function subtract(BigInteger $y) |
||
| 493 | |||
| 494 | /** |
||
| 495 | * Performs subtraction. |
||
| 496 | * |
||
| 497 | * @param array $x_value |
||
| 498 | * @param bool $x_negative |
||
| 499 | * @param array $y_value |
||
| 500 | * @param bool $y_negative |
||
| 501 | * |
||
| 502 | * @return array |
||
| 503 | */ |
||
| 504 | private static function _subtract($x_value, $x_negative, $y_value, $y_negative) |
||
| 583 | |||
| 584 | /** |
||
| 585 | * Multiplies two BigIntegers. |
||
| 586 | * |
||
| 587 | * Here's an example: |
||
| 588 | * <code> |
||
| 589 | * <?php |
||
| 590 | * $a = new \Jose\Util\ger('10'); |
||
| 591 | * $b = new \Jose\Util\ger('20'); |
||
| 592 | * |
||
| 593 | * $c = $a->multiply($b); |
||
| 594 | * |
||
| 595 | * echo $c->toString(); // outputs 200 |
||
| 596 | * ?> |
||
| 597 | * </code> |
||
| 598 | * |
||
| 599 | * @param \Jose\Util\Integer $x |
||
| 600 | * |
||
| 601 | * @return \Jose\Util\BigInteger |
||
| 602 | */ |
||
| 603 | public function multiply(BigInteger $x) |
||
| 610 | |||
| 611 | /** |
||
| 612 | * Performs multiplication. |
||
| 613 | * |
||
| 614 | * @param array $x_value |
||
| 615 | * @param bool $x_negative |
||
| 616 | * @param array $y_value |
||
| 617 | * @param bool $y_negative |
||
| 618 | * |
||
| 619 | * @return array |
||
| 620 | */ |
||
| 621 | private static function _multiply($x_value, $x_negative, $y_value, $y_negative) |
||
| 640 | |||
| 641 | /** |
||
| 642 | * Performs long multiplication on two BigIntegers. |
||
| 643 | * |
||
| 644 | * Modeled after 'multiply' in MutableBigInteger.java. |
||
| 645 | * |
||
| 646 | * @param array $x_value |
||
| 647 | * @param array $y_value |
||
| 648 | * |
||
| 649 | * @return array |
||
| 650 | */ |
||
| 651 | private static function _regularMultiply($x_value, $y_value) |
||
| 703 | |||
| 704 | /** |
||
| 705 | * Performs Karatsuba multiplication on two BigIntegers. |
||
| 706 | * |
||
| 707 | * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and |
||
| 708 | * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}. |
||
| 709 | * |
||
| 710 | * @param array $x_value |
||
| 711 | * @param array $y_value |
||
| 712 | * |
||
| 713 | * @return array |
||
| 714 | */ |
||
| 715 | private static function _karatsuba($x_value, $y_value) |
||
| 745 | |||
| 746 | /** |
||
| 747 | * Performs squaring. |
||
| 748 | * |
||
| 749 | * @param array $x |
||
| 750 | * |
||
| 751 | * @return array |
||
| 752 | */ |
||
| 753 | private static function _square($x = false) |
||
| 759 | |||
| 760 | /** |
||
| 761 | * Performs traditional squaring on two BigIntegers. |
||
| 762 | * |
||
| 763 | * Squaring can be done faster than multiplying a number by itself can be. See |
||
| 764 | * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} / |
||
| 765 | * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information. |
||
| 766 | * |
||
| 767 | * @param array $value |
||
| 768 | * |
||
| 769 | * @return array |
||
| 770 | */ |
||
| 771 | private static function _baseSquare($value) |
||
| 799 | |||
| 800 | /** |
||
| 801 | * Performs Karatsuba "squaring" on two BigIntegers. |
||
| 802 | * |
||
| 803 | * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and |
||
| 804 | * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}. |
||
| 805 | * |
||
| 806 | * @param array $value |
||
| 807 | * |
||
| 808 | * @return array |
||
| 809 | */ |
||
| 810 | private static function _karatsubaSquare($value) |
||
| 837 | |||
| 838 | /** |
||
| 839 | * Divides two BigIntegers. |
||
| 840 | * |
||
| 841 | * Returns an array whose first element contains the quotient and whose second element contains the |
||
| 842 | * "common residue". If the remainder would be positive, the "common residue" and the remainder are the |
||
| 843 | * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder |
||
| 844 | * and the divisor (basically, the "common residue" is the first positive modulo). |
||
| 845 | * |
||
| 846 | * Here's an example: |
||
| 847 | * <code> |
||
| 848 | * <?php |
||
| 849 | * $a = new \Jose\Util\ger('10'); |
||
| 850 | * $b = new \Jose\Util\ger('20'); |
||
| 851 | * |
||
| 852 | * list($quotient, $remainder) = $a->divide($b); |
||
| 853 | * |
||
| 854 | * echo $quotient->toString(); // outputs 0 |
||
| 855 | * echo "\r\n"; |
||
| 856 | * echo $remainder->toString(); // outputs 10 |
||
| 857 | * ?> |
||
| 858 | * </code> |
||
| 859 | * |
||
| 860 | * @param \Jose\Util\Integer $y |
||
| 861 | * |
||
| 862 | * @return array |
||
| 863 | * |
||
| 864 | */ |
||
| 865 | public function divide(BigInteger $y) |
||
| 878 | |||
| 879 | /** |
||
| 880 | * Divides a BigInteger by a regular integer. |
||
| 881 | * |
||
| 882 | * abc / x = a00 / x + b0 / x + c / x |
||
| 883 | * |
||
| 884 | * @param array $dividend |
||
| 885 | * @param array $divisor |
||
| 886 | * |
||
| 887 | * @return array |
||
| 888 | */ |
||
| 889 | private static function _divide_digit($dividend, $divisor) |
||
| 902 | |||
| 903 | /** |
||
| 904 | * Performs modular exponentiation. |
||
| 905 | * |
||
| 906 | * Here's an example: |
||
| 907 | * <code> |
||
| 908 | * <?php |
||
| 909 | * $a = new \Jose\Util\ger('10'); |
||
| 910 | * $b = new \Jose\Util\ger('20'); |
||
| 911 | * $c = new \Jose\Util\ger('30'); |
||
| 912 | * |
||
| 913 | * $c = $a->modPow($b, $c); |
||
| 914 | * |
||
| 915 | * echo $c->toString(); // outputs 10 |
||
| 916 | * ?> |
||
| 917 | * </code> |
||
| 918 | * |
||
| 919 | * @param \Jose\Util\Integer $e |
||
| 920 | * @param \Jose\Util\Integer $n |
||
| 921 | * |
||
| 922 | * @return \Jose\Util\BigInteger |
||
| 923 | * |
||
| 924 | * and although the approach involving repeated squaring does vastly better, it, too, is impractical |
||
| 925 | * for our purposes. The reason being that division - by far the most complicated and time-consuming |
||
| 926 | * of the basic operations (eg. +,-,*,/) - occurs multiple times within it. |
||
| 927 | * |
||
| 928 | * Modular reductions resolve this issue. Although an individual modular reduction takes more time |
||
| 929 | * then an individual division, when performed in succession (with the same modulo), they're a lot faster. |
||
| 930 | * |
||
| 931 | * The two most commonly used modular reductions are Barrett and Montgomery reduction. Montgomery reduction, |
||
| 932 | * although faster, only works when the gcd of the modulo and of the base being used is 1. In RSA, when the |
||
| 933 | * base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because |
||
| 934 | * the product of two odd numbers is odd), but what about when RSA isn't used? |
||
| 935 | * |
||
| 936 | * In contrast, Barrett reduction has no such constraint. As such, some bigint implementations perform a |
||
| 937 | * Barrett reduction after every operation in the modpow function. Others perform Barrett reductions when the |
||
| 938 | * modulo is even and Montgomery reductions when the modulo is odd. BigInteger.java's modPow method, however, |
||
| 939 | * uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and |
||
| 940 | * the other, a power of two - and recombine them, later. This is the method that this modPow function uses. |
||
| 941 | * {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates. |
||
| 942 | */ |
||
| 943 | public function modPow(BigInteger $e, BigInteger $n) |
||
| 963 | |||
| 964 | /** |
||
| 965 | * Performs modular exponentiation. |
||
| 966 | * |
||
| 967 | * Alias for modPow(). |
||
| 968 | * |
||
| 969 | * @param \Jose\Util\Integer $e |
||
| 970 | * @param \Jose\Util\Integer $n |
||
| 971 | * |
||
| 972 | * @return \Jose\Util\BigInteger |
||
| 973 | */ |
||
| 974 | public function powMod(BigInteger $e, BigInteger $n) |
||
| 978 | |||
| 979 | /** |
||
| 980 | * Barrett Modular Reduction. |
||
| 981 | * |
||
| 982 | * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / |
||
| 983 | * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, |
||
| 984 | * so as not to require negative numbers (initially, this script didn't support negative numbers). |
||
| 985 | * |
||
| 986 | * Employs "folding", as described at |
||
| 987 | * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from |
||
| 988 | * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." |
||
| 989 | * |
||
| 990 | * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that |
||
| 991 | * usable on account of (1) its not using reasonable radix points as discussed in |
||
| 992 | * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable |
||
| 993 | * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that |
||
| 994 | * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line |
||
| 995 | * comments for details. |
||
| 996 | * |
||
| 997 | * @param array $n |
||
| 998 | * @param array $m |
||
| 999 | * |
||
| 1000 | * @return array |
||
| 1001 | */ |
||
| 1002 | private static function _barrett($n, $m) |
||
| 1087 | |||
| 1088 | /** |
||
| 1089 | * (Regular) Barrett Modular Reduction. |
||
| 1090 | * |
||
| 1091 | * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this |
||
| 1092 | * is that this function does not fold the denominator into a smaller form. |
||
| 1093 | * |
||
| 1094 | * @param array $x |
||
| 1095 | * @param array $n |
||
| 1096 | * |
||
| 1097 | * @return array |
||
| 1098 | */ |
||
| 1099 | private static function _regularBarrett($x, $n) |
||
| 1159 | |||
| 1160 | /** |
||
| 1161 | * Performs long multiplication up to $stop digits. |
||
| 1162 | * |
||
| 1163 | * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved. |
||
| 1164 | * |
||
| 1165 | * @param array $x_value |
||
| 1166 | * @param bool $x_negative |
||
| 1167 | * @param array $y_value |
||
| 1168 | * @param bool $y_negative |
||
| 1169 | * @param int $stop |
||
| 1170 | * |
||
| 1171 | * @return array |
||
| 1172 | */ |
||
| 1173 | private static function _multiplyLower($x_value, $x_negative, $y_value, $y_negative, $stop) |
||
| 1236 | |||
| 1237 | /** |
||
| 1238 | * Montgomery Modular Reduction. |
||
| 1239 | * |
||
| 1240 | * ($x->_prepMontgomery($n))->_montgomery($n) yields $x % $n. |
||
| 1241 | * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=170 MPM 6.3} provides insights on how this can be |
||
| 1242 | * improved upon (basically, by using the comba method). gcd($n, 2) must be equal to one for this function |
||
| 1243 | * to work correctly. |
||
| 1244 | * |
||
| 1245 | * @param array $x |
||
| 1246 | * @param array $n |
||
| 1247 | * |
||
| 1248 | * @return array |
||
| 1249 | */ |
||
| 1250 | private static function _montgomery($x, $n) |
||
| 1283 | |||
| 1284 | /** |
||
| 1285 | * Modular Inverse of a number mod 2**26 (eg. 67108864). |
||
| 1286 | * |
||
| 1287 | * Based off of the bnpInvDigit function implemented and justified in the following URL: |
||
| 1288 | * |
||
| 1289 | * {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js} |
||
| 1290 | * |
||
| 1291 | * The following URL provides more info: |
||
| 1292 | * |
||
| 1293 | * {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85} |
||
| 1294 | * |
||
| 1295 | * As for why we do all the bitmasking... strange things can happen when converting from floats to ints. For |
||
| 1296 | * instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields |
||
| 1297 | * int(-2147483648). To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't |
||
| 1298 | * auto-converted to floats. The outermost bitmask is present because without it, there's no guarantee that |
||
| 1299 | * the "residue" returned would be the so-called "common residue". We use fmod, in the last step, because the |
||
| 1300 | * maximum possible $x is 26 bits and the maximum $result is 16 bits. Thus, we have to be able to handle up to |
||
| 1301 | * 40 bits, which only 64-bit floating points will support. |
||
| 1302 | * |
||
| 1303 | * Thanks to Pedro Gimeno Fortea for input! |
||
| 1304 | * |
||
| 1305 | * @param array $x |
||
| 1306 | * |
||
| 1307 | * @return int |
||
| 1308 | */ |
||
| 1309 | private function _modInverse67108864($x) // 2**26 == 67,108,864 |
||
| 1319 | |||
| 1320 | /** |
||
| 1321 | * Calculates modular inverses. |
||
| 1322 | * |
||
| 1323 | * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. |
||
| 1324 | * |
||
| 1325 | * Here's an example: |
||
| 1326 | * <code> |
||
| 1327 | * <?php |
||
| 1328 | * $a = new \Jose\Util\teger(30); |
||
| 1329 | * $b = new \Jose\Util\teger(17); |
||
| 1330 | * |
||
| 1331 | * $c = $a->modInverse($b); |
||
| 1332 | * echo $c->toString(); // outputs 4 |
||
| 1333 | * |
||
| 1334 | * echo "\r\n"; |
||
| 1335 | * |
||
| 1336 | * $d = $a->multiply($c); |
||
| 1337 | * list(, $d) = $d->divide($b); |
||
| 1338 | * echo $d; // outputs 1 (as per the definition of modular inverse) |
||
| 1339 | * ?> |
||
| 1340 | * </code> |
||
| 1341 | * |
||
| 1342 | * @param \Jose\Util\Integer $n |
||
| 1343 | * |
||
| 1344 | * @return \Jose\Util\eger|false |
||
| 1345 | * |
||
| 1346 | */ |
||
| 1347 | public function modInverse(BigInteger $n) |
||
| 1354 | |||
| 1355 | /** |
||
| 1356 | * Calculates the greatest common divisor and Bezout's identity. |
||
| 1357 | * |
||
| 1358 | * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that |
||
| 1359 | * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which |
||
| 1360 | * combination is returned is dependant upon which mode is in use. See |
||
| 1361 | * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. |
||
| 1362 | * |
||
| 1363 | * Here's an example: |
||
| 1364 | * <code> |
||
| 1365 | * <?php |
||
| 1366 | * $a = new \Jose\Util\eger(693); |
||
| 1367 | * $b = new \Jose\Util\eger(609); |
||
| 1368 | * |
||
| 1369 | * extract($a->extendedGCD($b)); |
||
| 1370 | * |
||
| 1371 | * echo $gcd->toString() . "\r\n"; // outputs 21 |
||
| 1372 | * echo $a->toString() * $x->toString() + $b->toString() * $y->toString(); // outputs 21 |
||
| 1373 | * ?> |
||
| 1374 | * </code> |
||
| 1375 | * |
||
| 1376 | * @param \Jose\Util\Integer $n |
||
| 1377 | * |
||
| 1378 | * @return \Jose\Util\BigInteger |
||
| 1379 | * |
||
| 1380 | * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=19 HAC 14.61}. As the text above 14.61 notes, |
||
| 1381 | * the more traditional algorithim requires "relatively costly multiple-precision divisions". |
||
| 1382 | */ |
||
| 1383 | public function extendedGCD(BigInteger $n) |
||
| 1393 | |||
| 1394 | /** |
||
| 1395 | * Calculates the greatest common divisor. |
||
| 1396 | * |
||
| 1397 | * Say you have 693 and 609. The GCD is 21. |
||
| 1398 | * |
||
| 1399 | * Here's an example: |
||
| 1400 | * <code> |
||
| 1401 | * <?php |
||
| 1402 | * $a = new \Jose\Util\eger(693); |
||
| 1403 | * $b = new \Jose\Util\eger(609); |
||
| 1404 | * |
||
| 1405 | * $gcd = a->extendedGCD($b); |
||
| 1406 | * |
||
| 1407 | * echo $gcd->toString() . "\r\n"; // outputs 21 |
||
| 1408 | * ?> |
||
| 1409 | * </code> |
||
| 1410 | * |
||
| 1411 | * @param \Jose\Util\Integer $n |
||
| 1412 | * |
||
| 1413 | * @return \Jose\Util\BigInteger |
||
| 1414 | */ |
||
| 1415 | public function gcd(BigInteger $n) |
||
| 1421 | |||
| 1422 | /** |
||
| 1423 | * Absolute value. |
||
| 1424 | * |
||
| 1425 | * @return \Jose\Util\BigInteger |
||
| 1426 | */ |
||
| 1427 | public function abs() |
||
| 1435 | |||
| 1436 | /** |
||
| 1437 | * Compares two numbers. |
||
| 1438 | * |
||
| 1439 | * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is |
||
| 1440 | * demonstrated thusly: |
||
| 1441 | * |
||
| 1442 | * $x > $y: $x->compare($y) > 0 |
||
| 1443 | * $x < $y: $x->compare($y) < 0 |
||
| 1444 | * $x == $y: $x->compare($y) == 0 |
||
| 1445 | * |
||
| 1446 | * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). |
||
| 1447 | * |
||
| 1448 | * @param \Jose\Util\Integer $y |
||
| 1449 | * |
||
| 1450 | * @return int < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. |
||
| 1451 | * |
||
| 1452 | */ |
||
| 1453 | public function compare(BigInteger $y) |
||
| 1457 | |||
| 1458 | /** |
||
| 1459 | * Compares two numbers. |
||
| 1460 | * |
||
| 1461 | * @param array $x_value |
||
| 1462 | * @param bool $x_negative |
||
| 1463 | * @param array $y_value |
||
| 1464 | * @param bool $y_negative |
||
| 1465 | * |
||
| 1466 | * @return int |
||
| 1467 | */ |
||
| 1468 | private static function _compare($x_value, $x_negative, $y_value, $y_negative) |
||
| 1492 | |||
| 1493 | /** |
||
| 1494 | * Tests the equality of two numbers. |
||
| 1495 | * |
||
| 1496 | * If you need to see if one number is greater than or less than another number, use BigInteger::compare() |
||
| 1497 | * |
||
| 1498 | * @param \Jose\Util\Integer $x |
||
| 1499 | * |
||
| 1500 | * @return bool |
||
| 1501 | */ |
||
| 1502 | public function equals(BigInteger $x) |
||
| 1506 | |||
| 1507 | /** |
||
| 1508 | * Set Precision. |
||
| 1509 | * |
||
| 1510 | * Some bitwise operations give different results depending on the precision being used. Examples include left |
||
| 1511 | * shift, not, and rotates. |
||
| 1512 | * |
||
| 1513 | * @param int $bits |
||
| 1514 | */ |
||
| 1515 | public function setPrecision($bits) |
||
| 1533 | |||
| 1534 | /** |
||
| 1535 | * Get Precision. |
||
| 1536 | * |
||
| 1537 | * @return int |
||
| 1538 | */ |
||
| 1539 | public function getPrecision() |
||
| 1543 | |||
| 1544 | /** |
||
| 1545 | * Logical And. |
||
| 1546 | * |
||
| 1547 | * @param \Jose\Util\Integer $x |
||
| 1548 | * |
||
| 1549 | * |
||
| 1550 | * @return \Jose\Util\BigInteger |
||
| 1551 | */ |
||
| 1552 | public function bitwise_and(BigInteger $x) |
||
| 1559 | |||
| 1560 | /** |
||
| 1561 | * Logical Or. |
||
| 1562 | * |
||
| 1563 | * @param \Jose\Util\Integer $x |
||
| 1564 | * |
||
| 1565 | * |
||
| 1566 | * @return \Jose\Util\BigInteger |
||
| 1567 | */ |
||
| 1568 | public function bitwise_or(BigInteger $x) |
||
| 1575 | |||
| 1576 | /** |
||
| 1577 | * Logical Exclusive-Or. |
||
| 1578 | * |
||
| 1579 | * @param \Jose\Util\Integer $x |
||
| 1580 | * |
||
| 1581 | * |
||
| 1582 | * @return \Jose\Util\BigInteger |
||
| 1583 | */ |
||
| 1584 | public function bitwise_xor(BigInteger $x) |
||
| 1591 | |||
| 1592 | /** |
||
| 1593 | * Logical Not. |
||
| 1594 | * |
||
| 1595 | * |
||
| 1596 | * @return \Jose\Util\BigInteger |
||
| 1597 | */ |
||
| 1598 | public function bitwise_not() |
||
| 1630 | |||
| 1631 | /** |
||
| 1632 | * Logical Right Shift. |
||
| 1633 | * |
||
| 1634 | * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. |
||
| 1635 | * |
||
| 1636 | * @param int $shift |
||
| 1637 | * |
||
| 1638 | * @return \Jose\Util\BigInteger |
||
| 1639 | * |
||
| 1640 | */ |
||
| 1641 | public function bitwise_rightShift($shift) |
||
| 1655 | |||
| 1656 | /** |
||
| 1657 | * Logical Left Shift. |
||
| 1658 | * |
||
| 1659 | * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. |
||
| 1660 | * |
||
| 1661 | * @param int $shift |
||
| 1662 | * |
||
| 1663 | * @return \Jose\Util\BigInteger |
||
| 1664 | * |
||
| 1665 | */ |
||
| 1666 | public function bitwise_leftShift($shift) |
||
| 1680 | |||
| 1681 | /** |
||
| 1682 | * Logical Left Rotate. |
||
| 1683 | * |
||
| 1684 | * Instead of the top x bits being dropped they're appended to the shifted bit string. |
||
| 1685 | * |
||
| 1686 | * @param int $shift |
||
| 1687 | * |
||
| 1688 | * @return \Jose\Util\BigInteger |
||
| 1689 | */ |
||
| 1690 | public function bitwise_leftRotate($shift) |
||
| 1726 | |||
| 1727 | /** |
||
| 1728 | * Logical Right Rotate. |
||
| 1729 | * |
||
| 1730 | * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. |
||
| 1731 | * |
||
| 1732 | * @param int $shift |
||
| 1733 | * |
||
| 1734 | * @return \Jose\Util\BigInteger |
||
| 1735 | */ |
||
| 1736 | public function bitwise_rightRotate($shift) |
||
| 1740 | |||
| 1741 | /** |
||
| 1742 | * Generates a random BigInteger. |
||
| 1743 | * |
||
| 1744 | * Byte length is equal to $length. Uses \phpseclib\Crypt\Random if it's loaded and mt_rand if it's not. |
||
| 1745 | * |
||
| 1746 | * @param int $length |
||
| 1747 | * |
||
| 1748 | * @return \Jose\Util\BigInteger |
||
| 1749 | */ |
||
| 1750 | private static function _random_number_helper($size) |
||
| 1770 | |||
| 1771 | /** |
||
| 1772 | * Generate a random number. |
||
| 1773 | * |
||
| 1774 | * Returns a random number between $min and $max where $min and $max |
||
| 1775 | * can be defined using one of the two methods: |
||
| 1776 | * |
||
| 1777 | * BigInteger::random($min, $max) |
||
| 1778 | * BigInteger::random($max, $min) |
||
| 1779 | * |
||
| 1780 | * @param \Jose\Util\eger $arg1 |
||
| 1781 | * @param \Jose\Util\eger $arg2 |
||
| 1782 | * |
||
| 1783 | * @return \Jose\Util\BigInteger |
||
| 1784 | */ |
||
| 1785 | public static function random(BigInteger $min, BigInteger $max) |
||
| 1840 | |||
| 1841 | /** |
||
| 1842 | * Generate a random prime number. |
||
| 1843 | * |
||
| 1844 | * If there's not a prime within the given range, false will be returned. |
||
| 1845 | * If more than $timeout seconds have elapsed, give up and return false. |
||
| 1846 | * |
||
| 1847 | * @param \Jose\Util\teger $min |
||
| 1848 | * @param \Jose\Util\teger $max |
||
| 1849 | * @param int $timeout |
||
| 1850 | * |
||
| 1851 | * @return Math_BigInteger|false |
||
| 1852 | * |
||
| 1853 | */ |
||
| 1854 | public static function randomPrime(BigInteger $min, BigInteger $max, $timeout = false) |
||
| 1933 | |||
| 1934 | /** |
||
| 1935 | * Make the current number odd. |
||
| 1936 | * |
||
| 1937 | * If the current number is odd it'll be unchanged. If it's even, one will be added to it. |
||
| 1938 | */ |
||
| 1939 | private function _make_odd() |
||
| 1954 | |||
| 1955 | /** |
||
| 1956 | * Normalize. |
||
| 1957 | * |
||
| 1958 | * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision |
||
| 1959 | * |
||
| 1960 | * @param \Jose\Util\BigInteger |
||
| 1961 | * |
||
| 1962 | * @return \Jose\Util\BigInteger |
||
| 1963 | */ |
||
| 1964 | private function _normalize($result) |
||
| 1975 | |||
| 1976 | /** |
||
| 1977 | * Trim. |
||
| 1978 | * |
||
| 1979 | * Removes leading zeros |
||
| 1980 | * |
||
| 1981 | * @param array $value |
||
| 1982 | * |
||
| 1983 | * @return \Jose\Util\BigInteger |
||
| 1984 | */ |
||
| 1985 | private static function _trim($value) |
||
| 1996 | |||
| 1997 | /** |
||
| 1998 | * Array Repeat. |
||
| 1999 | * |
||
| 2000 | * @param $input Array |
||
| 2001 | * @param $multiplier mixed |
||
| 2002 | * |
||
| 2003 | * @return array |
||
| 2004 | */ |
||
| 2005 | private static function _array_repeat($input, $multiplier) |
||
| 2009 | |||
| 2010 | /** |
||
| 2011 | * Logical Left Shift. |
||
| 2012 | * |
||
| 2013 | * Shifts binary strings $shift bits, essentially multiplying by 2**$shift. |
||
| 2014 | * |
||
| 2015 | * @param $x String |
||
| 2016 | * @param $shift Integer |
||
| 2017 | * |
||
| 2018 | * @return string |
||
| 2019 | */ |
||
| 2020 | private static function _base256_lshift(&$x, $shift) |
||
| 2038 | |||
| 2039 | /** |
||
| 2040 | * Single digit division. |
||
| 2041 | * |
||
| 2042 | * Even if int64 is being used the division operator will return a float64 value |
||
| 2043 | * if the dividend is not evenly divisible by the divisor. Since a float64 doesn't |
||
| 2044 | * have the precision of int64 this is a problem so, when int64 is being used, |
||
| 2045 | * we'll guarantee that the dividend is divisible by first subtracting the remainder. |
||
| 2046 | * |
||
| 2047 | * @param int $x |
||
| 2048 | * @param int $y |
||
| 2049 | * |
||
| 2050 | * @return int |
||
| 2051 | */ |
||
| 2052 | private static function _safe_divide($x, $y) |
||
| 2061 | } |
||
| 2062 |
Adding a
@returnannotation to a constructor is not recommended, since a constructor does not have a meaningful return value.Please refer to the PHP core documentation on constructors.