2007-07-02 04:19:55 +00:00
< ? php
/**
* Pure - PHP arbitrary precision integer arithmetic library .
*
* Supports base - 2 , base - 10 , base - 16 , and base - 256 numbers . Uses the GMP or BCMath extensions , if available ,
* and an internal implementation , otherwise .
*
2017-06-25 16:02:54 +00:00
* PHP version 5 and 7
2007-07-02 04:19:55 +00:00
*
2009-11-23 19:06:07 +00:00
* Here ' s an example of how to use this library :
2007-07-02 04:19:55 +00:00
* < code >
* < ? php
2019-11-07 05:41:40 +00:00
* $a = new \phpseclib3\Math\BigInteger ( 2 );
* $b = new \phpseclib3\Math\BigInteger ( 3 );
2007-07-02 04:19:55 +00:00
*
* $c = $a -> add ( $b );
*
* echo $c -> toString (); // outputs 5
* ?>
* </ code >
*
2013-12-10 19:10:37 +00:00
* @ author Jim Wigginton < terrafrost @ php . net >
2017-06-25 16:02:54 +00:00
* @ copyright 2017 Jim Wigginton
2013-12-10 19:10:37 +00:00
* @ license http :// www . opensource . org / licenses / mit - license . html MIT License
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
declare ( strict_types = 1 );
2019-11-07 05:41:40 +00:00
namespace phpseclib3\Math ;
2014-06-02 17:19:59 +00:00
2019-11-07 05:41:40 +00:00
use phpseclib3\Exception\BadConfigurationException ;
2022-08-18 13:05:57 +00:00
use phpseclib3\Exception\InvalidArgumentException ;
2023-09-25 16:14:46 +00:00
use phpseclib3\Exception\UnexpectedValueException ;
2022-02-21 13:43:51 +00:00
use phpseclib3\Math\BigInteger\Engines\Engine ;
2014-12-02 02:54:44 +00:00
2007-07-02 04:19:55 +00:00
/**
2009-04-18 14:57:54 +00:00
* Pure - PHP arbitrary precision integer arithmetic library . Supports base - 2 , base - 10 , base - 16 , and base - 256
2007-07-02 04:19:55 +00:00
* numbers .
*
* @ author Jim Wigginton < terrafrost @ php . net >
*/
2022-03-11 02:26:46 +00:00
class BigInteger implements \JsonSerializable
2013-12-03 18:34:41 +00:00
{
2014-12-07 21:33:39 +00:00
/**
2017-06-25 16:02:54 +00:00
* Main Engine
2014-12-07 21:33:39 +00:00
*
2022-02-21 13:43:51 +00:00
* @ var class - string < Engine >
2016-04-10 16:30:59 +00:00
*/
2017-06-25 16:02:54 +00:00
private static $mainEngine ;
2014-12-07 21:33:39 +00:00
/**
2017-06-25 16:02:54 +00:00
* Selected Engines
2014-12-07 21:33:39 +00:00
*
2022-02-21 13:43:51 +00:00
* @ var list < string >
2016-04-10 16:30:59 +00:00
*/
2017-06-25 16:02:54 +00:00
private static $engines ;
2014-12-07 21:33:39 +00:00
/**
2017-06-25 16:02:54 +00:00
* The actual BigInteger object
2014-12-07 21:33:39 +00:00
*
2017-06-25 16:02:54 +00:00
* @ var object
2016-04-10 16:30:59 +00:00
*/
2017-06-25 16:02:54 +00:00
private $value ;
2014-12-07 21:33:39 +00:00
2021-07-22 13:51:51 +00:00
/**
* Mode independent value used for serialization .
*
* @ see self :: __sleep ()
* @ see self :: __wakeup ()
* @ var string
*/
private $hex ;
/**
* Precision ( used only for serialization )
*
* @ see self :: __sleep ()
* @ see self :: __wakeup ()
* @ var int
*/
private $precision ;
2014-12-07 21:33:39 +00:00
/**
2017-06-25 16:02:54 +00:00
* Sets engine type .
2014-12-07 21:33:39 +00:00
*
2017-06-25 16:02:54 +00:00
* Throws an exception if the type is invalid
2014-12-08 14:54:44 +00:00
*
2022-02-21 13:43:51 +00:00
* @ param list < string > $modexps optional
2016-04-10 16:30:59 +00:00
*/
2022-06-04 15:31:21 +00:00
public static function setEngine ( string $main , array $modexps = [ 'DefaultEngine' ]) : void
2017-06-25 16:02:54 +00:00
{
self :: $engines = [];
2014-12-07 22:00:59 +00:00
2019-11-07 05:41:40 +00:00
$fqmain = 'phpseclib3\\Math\\BigInteger\\Engines\\' . $main ;
2017-06-25 16:02:54 +00:00
if ( ! class_exists ( $fqmain ) || ! method_exists ( $fqmain , 'isValidEngine' )) {
2022-08-18 13:05:57 +00:00
throw new InvalidArgumentException ( " $main is not a valid engine " );
2017-06-25 16:02:54 +00:00
}
if ( ! $fqmain :: isValidEngine ()) {
throw new BadConfigurationException ( " $main is not setup correctly on this system " );
}
2022-02-21 13:43:51 +00:00
/** @var class-string<Engine> $fqmain */
2017-06-25 16:02:54 +00:00
self :: $mainEngine = $fqmain ;
2014-12-07 21:33:39 +00:00
2017-06-25 16:02:54 +00:00
$found = false ;
foreach ( $modexps as $modexp ) {
try {
$fqmain :: setModExpEngine ( $modexp );
$found = true ;
break ;
} catch ( \Exception $e ) {
}
}
2007-07-02 04:19:55 +00:00
2017-06-25 16:02:54 +00:00
if ( ! $found ) {
throw new BadConfigurationException ( " No valid modular exponentiation engine found for $main " );
}
2009-11-23 19:06:07 +00:00
2017-06-25 16:02:54 +00:00
self :: $engines = [ $main , $modexp ];
}
2010-01-21 00:52:11 +00:00
2018-12-02 16:58:07 +00:00
/**
* Returns the engine type
*
* @ return string []
*/
2022-06-04 15:31:21 +00:00
public static function getEngine () : array
2018-12-02 16:58:07 +00:00
{
self :: initialize_static_variables ();
return self :: $engines ;
}
2007-07-02 04:19:55 +00:00
/**
2018-12-02 16:41:24 +00:00
* Initialize static variables
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
private static function initialize_static_variables () : void
2007-07-02 04:19:55 +00:00
{
2017-06-25 16:02:54 +00:00
if ( ! isset ( self :: $mainEngine )) {
$engines = [
2023-07-26 01:32:42 +00:00
[ 'GMP' , [ 'DefaultEngine' ]],
2023-07-08 18:27:16 +00:00
[ 'PHP64' , [ 'OpenSSL' ]],
2023-07-09 13:51:55 +00:00
[ 'BCMath' , [ 'OpenSSL' ]],
2022-07-23 02:45:53 +00:00
[ 'PHP32' , [ 'OpenSSL' ]],
2023-07-08 18:27:16 +00:00
[ 'PHP64' , [ 'DefaultEngine' ]],
[ 'PHP32' , [ 'DefaultEngine' ]],
2017-06-25 16:02:54 +00:00
];
2023-09-22 08:07:03 +00:00
2017-06-25 16:02:54 +00:00
foreach ( $engines as $engine ) {
try {
2023-07-26 01:32:42 +00:00
self :: setEngine ( $engine [ 0 ], $engine [ 1 ]);
2023-09-22 08:07:03 +00:00
return ;
2017-10-01 06:55:00 +00:00
} catch ( \Exception $e ) {
2009-11-23 19:06:07 +00:00
}
2017-06-25 16:02:54 +00:00
}
2023-09-22 08:07:03 +00:00
2023-11-02 01:51:12 +00:00
throw new UnexpectedValueException ( 'No valid BigInteger found. This is only possible when JIT is enabled on Windows and neither the GMP or BCMath extensions are available so either disable JIT or install GMP / BCMath' );
2007-07-02 04:19:55 +00:00
}
2018-12-02 16:41:24 +00:00
}
/**
* Converts base - 2 , base - 10 , base - 16 , and binary strings ( base - 256 ) to BigIntegers .
*
* If the second parameter - $base - is negative , then it will be assumed that the number ' s are encoded using
* two ' s compliment . The sole exception to this is - 10 , which is treated the same as 10 is .
*
2024-05-25 20:20:57 +00:00
* @ param string | int | Engine $x Base - 10 number or base - $base number if $base set .
2018-12-02 16:41:24 +00:00
*/
2022-06-04 15:31:21 +00:00
public function __construct ( $x = 0 , int $base = 10 )
2018-12-02 16:41:24 +00:00
{
self :: initialize_static_variables ();
2007-07-02 04:19:55 +00:00
2017-06-25 16:02:54 +00:00
if ( $x instanceof self :: $mainEngine ) {
$this -> value = clone $x ;
2024-05-25 20:20:57 +00:00
} elseif ( $x instanceof Engine ) {
2017-06-25 16:02:54 +00:00
$this -> value = new static ( " $x " );
$this -> value -> setPrecision ( $x -> getPrecision ());
} else {
$this -> value = new self :: $mainEngine ( $x , $base );
2007-07-02 04:19:55 +00:00
}
2017-06-25 16:02:54 +00:00
}
2007-07-02 04:19:55 +00:00
2017-06-25 16:02:54 +00:00
/**
* Converts a BigInteger to a base - 10 number .
*/
2022-06-04 15:31:21 +00:00
public function toString () : string
2017-06-25 16:02:54 +00:00
{
return $this -> value -> toString ();
}
2007-07-02 04:19:55 +00:00
2017-06-25 16:02:54 +00:00
/**
* __toString () magic method
*/
public function __toString ()
{
2022-02-17 02:25:59 +00:00
return ( string ) $this -> value ;
2017-06-25 16:02:54 +00:00
}
2007-07-02 04:19:55 +00:00
2017-06-25 16:02:54 +00:00
/**
* __debugInfo () magic method
*
* Will be called , automatically , when print_r () or var_dump () are called
*/
public function __debugInfo ()
{
return $this -> value -> __debugInfo ();
2007-07-02 04:19:55 +00:00
}
/**
* Converts a BigInteger to a byte string ( eg . base - 256 ) .
*/
2022-06-04 15:31:21 +00:00
public function toBytes ( bool $twos_compliment = false ) : string
2007-07-02 04:19:55 +00:00
{
2017-06-25 16:02:54 +00:00
return $this -> value -> toBytes ( $twos_compliment );
2007-07-02 04:19:55 +00:00
}
2009-11-03 22:00:10 +00:00
/**
2017-06-25 16:02:54 +00:00
* Converts a BigInteger to a hex string ( eg . base - 16 ) .
2009-11-03 22:00:10 +00:00
*/
2022-06-04 15:31:21 +00:00
public function toHex ( bool $twos_compliment = false ) : string
2009-11-03 22:00:10 +00:00
{
2017-06-25 16:02:54 +00:00
return $this -> value -> toHex ( $twos_compliment );
2009-11-23 19:06:07 +00:00
}
/**
* Converts a BigInteger to a bit string ( eg . base - 2 ) .
*
* Negative numbers are saved as positive numbers , unless $twos_compliment is set to true , at which point , they ' re
* saved as two ' s compliment .
*/
2022-06-04 15:31:21 +00:00
public function toBits ( bool $twos_compliment = false ) : string
2009-11-23 19:06:07 +00:00
{
2019-04-08 13:02:48 +00:00
return $this -> value -> toBits ( $twos_compliment );
2009-11-03 22:00:10 +00:00
}
2007-07-02 04:19:55 +00:00
/**
2017-06-25 16:02:54 +00:00
* Adds two BigIntegers .
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
public function add ( BigInteger $y ) : BigInteger
2007-07-02 04:19:55 +00:00
{
2017-06-25 16:02:54 +00:00
return new static ( $this -> value -> add ( $y -> value ));
2007-07-02 04:19:55 +00:00
}
2009-02-16 23:11:01 +00:00
/**
2017-06-25 16:02:54 +00:00
* Subtracts two BigIntegers .
2009-02-16 23:11:01 +00:00
*/
2022-06-04 15:31:21 +00:00
public function subtract ( BigInteger $y ) : BigInteger
2009-02-16 23:11:01 +00:00
{
2017-06-25 16:02:54 +00:00
return new static ( $this -> value -> subtract ( $y -> value ));
2009-02-16 23:11:01 +00:00
}
2010-01-21 00:52:11 +00:00
/**
2017-06-25 16:02:54 +00:00
* Multiplies two BigIntegers
2010-01-21 00:52:11 +00:00
*/
2022-06-04 15:31:21 +00:00
public function multiply ( BigInteger $x ) : BigInteger
2010-01-21 00:52:11 +00:00
{
2017-06-25 16:02:54 +00:00
return new static ( $this -> value -> multiply ( $x -> value ));
2010-01-21 00:52:11 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Divides two BigIntegers .
2010-01-21 00:52:11 +00:00
*
2017-06-25 16:02:54 +00:00
* Returns an array whose first element contains the quotient and whose second element contains the
* " common residue " . If the remainder would be positive , the " common residue " and the remainder are the
* same . If the remainder would be negative , the " common residue " is equal to the sum of the remainder
* and the divisor ( basically , the " common residue " is the first positive modulo ) .
2009-11-23 19:06:07 +00:00
*
* Here ' s an example :
2017-06-25 16:02:54 +00:00
* < code >
* < ? php
2019-11-07 05:41:40 +00:00
* $a = new \phpseclib3\Math\BigInteger ( '10' );
* $b = new \phpseclib3\Math\BigInteger ( '20' );
2016-04-30 21:23:35 +00:00
*
2017-06-25 16:02:54 +00:00
* list ( $quotient , $remainder ) = $a -> divide ( $b );
*
* echo $quotient -> toString (); // outputs 0
* echo " \r \n " ;
* echo $remainder -> toString (); // outputs 10
* ?>
* </ code >
*
2017-11-05 20:35:27 +00:00
* @ return BigInteger []
2016-04-30 21:23:35 +00:00
*/
2022-06-04 15:31:21 +00:00
public function divide ( BigInteger $y ) : array
2016-04-30 21:23:35 +00:00
{
2022-06-04 15:31:21 +00:00
[ $q , $r ] = $this -> value -> divide ( $y -> value );
2017-06-25 16:02:54 +00:00
return [
new static ( $q ),
2022-07-23 02:45:53 +00:00
new static ( $r ),
2017-06-25 16:02:54 +00:00
];
2016-04-30 21:23:35 +00:00
}
2007-07-02 04:19:55 +00:00
/**
2017-06-25 16:02:54 +00:00
* Calculates modular inverses .
2007-07-02 04:19:55 +00:00
*
2017-06-25 16:02:54 +00:00
* Say you have ( 30 mod 17 * x mod 17 ) mod 17 == 1. x can be found using modular inverses .
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
public function modInverse ( BigInteger $n ) : BigInteger
2007-07-02 04:19:55 +00:00
{
2017-06-25 16:02:54 +00:00
return new static ( $this -> value -> modInverse ( $n -> value ));
2007-07-02 04:19:55 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Calculates modular inverses .
2007-07-02 04:19:55 +00:00
*
2017-06-25 16:02:54 +00:00
* Say you have ( 30 mod 17 * x mod 17 ) mod 17 == 1. x can be found using modular inverses .
2022-02-17 02:25:59 +00:00
*
* @ return BigInteger []
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
public function extendedGCD ( BigInteger $n ) : array
2007-07-02 04:19:55 +00:00
{
2017-06-25 16:02:54 +00:00
extract ( $this -> value -> extendedGCD ( $n -> value ));
2017-12-04 10:11:43 +00:00
/**
* @ var BigInteger $gcd
* @ var BigInteger $x
* @ var BigInteger $y
*/
2017-06-25 16:02:54 +00:00
return [
'gcd' => new static ( $gcd ),
'x' => new static ( $x ),
2022-07-23 02:45:53 +00:00
'y' => new static ( $y ),
2017-06-25 16:02:54 +00:00
];
2007-07-02 04:19:55 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Calculates the greatest common divisor
*
* Say you have 693 and 609. The GCD is 21.
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
public function gcd ( BigInteger $n ) : BigInteger
2007-07-02 04:19:55 +00:00
{
2017-06-25 16:02:54 +00:00
return new static ( $this -> value -> gcd ( $n -> value ));
2007-07-02 04:19:55 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Absolute value .
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
public function abs () : BigInteger
2007-07-02 04:19:55 +00:00
{
2022-02-17 02:25:59 +00:00
return new static ( $this -> value -> abs ());
2007-07-02 04:19:55 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Set Precision
2007-07-02 04:19:55 +00:00
*
2017-06-25 16:02:54 +00:00
* Some bitwise operations give different results depending on the precision being used . Examples include left
* shift , not , and rotates .
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
public function setPrecision ( int $bits ) : void
2007-07-02 04:19:55 +00:00
{
2017-06-25 16:02:54 +00:00
$this -> value -> setPrecision ( $bits );
2007-07-02 04:19:55 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Get Precision
2007-07-02 04:19:55 +00:00
*
2017-06-25 16:02:54 +00:00
* Returns the precision if it exists , false if it doesn ' t
2007-07-02 04:19:55 +00:00
*
2017-06-25 16:02:54 +00:00
* @ return int | bool
2007-07-02 04:19:55 +00:00
*/
2017-06-25 16:02:54 +00:00
public function getPrecision ()
2007-07-02 04:19:55 +00:00
{
2017-06-25 16:02:54 +00:00
return $this -> value -> getPrecision ();
2009-11-23 19:06:07 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Serialize
2009-11-23 19:06:07 +00:00
*
2017-06-25 16:02:54 +00:00
* Will be called , automatically , when serialize () is called on a BigInteger object .
2009-11-23 19:06:07 +00:00
*
2021-07-22 13:51:51 +00:00
* __sleep () / __wakeup () have been around since PHP 4.0
2017-06-25 16:02:54 +00:00
*
2021-07-22 13:51:51 +00:00
* \Serializable was introduced in PHP 5.1 and deprecated in PHP 8.1 :
* https :// wiki . php . net / rfc / phase_out_serializable
*
* __serialize () / __unserialize () were introduced in PHP 7.4 :
* https :// wiki . php . net / rfc / custom_object_serialization
2017-06-25 16:02:54 +00:00
*
2022-02-21 13:43:51 +00:00
* @ return array
2009-11-23 19:06:07 +00:00
*/
2021-07-22 13:51:51 +00:00
public function __sleep ()
2009-11-23 19:06:07 +00:00
{
2021-07-22 13:51:51 +00:00
$this -> hex = $this -> toHex ( true );
$vars = [ 'hex' ];
if ( $this -> getPrecision () > 0 ) {
$vars [] = 'precision' ;
2009-11-23 19:06:07 +00:00
}
2021-07-22 13:51:51 +00:00
return $vars ;
2009-11-23 19:06:07 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Serialize
2009-11-23 19:06:07 +00:00
*
2017-06-25 16:02:54 +00:00
* Will be called , automatically , when unserialize () is called on a BigInteger object .
2009-11-23 19:06:07 +00:00
*/
2022-06-04 15:31:21 +00:00
public function __wakeup () : void
2009-11-23 19:06:07 +00:00
{
2021-07-22 13:51:51 +00:00
$temp = new static ( $this -> hex , - 16 );
2017-06-25 16:02:54 +00:00
$this -> value = $temp -> value ;
2021-07-22 13:51:51 +00:00
if ( $this -> precision > 0 ) {
2017-06-25 16:02:54 +00:00
// recalculate $this->bitmask
2021-07-22 13:51:51 +00:00
$this -> setPrecision ( $this -> precision );
2017-06-25 16:02:54 +00:00
}
2007-07-02 04:19:55 +00:00
}
2022-03-11 02:26:46 +00:00
/**
* JSON Serialize
*
* Will be called , automatically , when json_encode () is called on a BigInteger object .
2023-02-27 11:32:24 +00:00
*
* @ return array { hex : string , precision ? : int ]
2022-03-11 02:26:46 +00:00
*/
2022-03-18 17:47:40 +00:00
#[\ReturnTypeWillChange]
2022-06-04 15:31:21 +00:00
public function jsonSerialize () : array
2022-03-11 02:26:46 +00:00
{
$result = [ 'hex' => $this -> toHex ( true )];
if ( $this -> precision > 0 ) {
$result [ 'precision' ] = $this -> getPrecision ();
}
return $result ;
}
2016-10-19 12:45:42 +00:00
/**
2017-06-25 16:02:54 +00:00
* Performs modular exponentiation .
2016-10-19 12:45:42 +00:00
*/
2022-06-04 15:31:21 +00:00
public function powMod ( BigInteger $e , BigInteger $n ) : BigInteger
2016-10-19 12:45:42 +00:00
{
2017-06-25 16:02:54 +00:00
return new static ( $this -> value -> powMod ( $e -> value , $n -> value ));
2016-10-19 12:45:42 +00:00
}
2013-08-07 04:17:49 +00:00
/**
2017-06-25 16:02:54 +00:00
* Performs modular exponentiation .
2013-08-07 04:17:49 +00:00
*/
2022-06-04 15:31:21 +00:00
public function modPow ( BigInteger $e , BigInteger $n ) : BigInteger
2013-08-07 04:17:49 +00:00
{
2017-06-25 16:02:54 +00:00
return new static ( $this -> value -> modPow ( $e -> value , $n -> value ));
2013-08-07 04:17:49 +00:00
}
2009-11-03 22:00:10 +00:00
/**
2017-06-25 16:02:54 +00:00
* Compares two numbers .
2007-07-02 04:19:55 +00:00
*
2022-02-17 02:25:59 +00:00
* Although one might think ! $x -> compare ( $y ) means $x != $y , it , in fact , means the opposite . The reason for this
* is demonstrated thusly :
2014-06-14 19:07:33 +00:00
*
2017-06-25 16:02:54 +00:00
* $x > $y : $x -> compare ( $y ) > 0
* $x < $y : $x -> compare ( $y ) < 0
* $x == $y : $x -> compare ( $y ) == 0
2014-06-14 19:07:33 +00:00
*
2017-06-25 16:02:54 +00:00
* Note how the same comparison operator is used . If you want to test for equality , use $x -> equals ( $y ) .
*
2020-12-30 11:05:54 +00:00
* { @ internal Could return $this -> subtract ( $x ), but that ' s not as fast as what we do do . }
*
2020-09-09 08:01:39 +00:00
* @ return int in case < 0 if $this is less than $y ; > 0 if $this is greater than $y , and 0 if they are equal .
2017-06-25 16:02:54 +00:00
* @ see self :: equals ()
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
public function compare ( BigInteger $y ) : int
2007-07-02 04:19:55 +00:00
{
2017-06-25 16:02:54 +00:00
return $this -> value -> compare ( $y -> value );
2007-07-02 04:19:55 +00:00
}
2009-11-03 22:00:10 +00:00
/**
2017-06-25 16:02:54 +00:00
* Tests the equality of two numbers .
2016-09-18 02:48:51 +00:00
*
2017-06-25 16:02:54 +00:00
* If you need to see if one number is greater than or less than another number , use BigInteger :: compare ()
2016-09-18 02:48:51 +00:00
*/
2022-06-04 15:31:21 +00:00
public function equals ( BigInteger $x ) : bool
2016-09-18 02:48:51 +00:00
{
2017-06-25 16:02:54 +00:00
return $this -> value -> equals ( $x -> value );
2016-09-18 02:48:51 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Logical Not
2009-11-03 22:00:10 +00:00
*/
2022-06-04 15:31:21 +00:00
public function bitwise_not () : BigInteger
2017-06-25 16:02:54 +00:00
{
return new static ( $this -> value -> bitwise_not ());
2010-02-21 07:45:31 +00:00
}
2009-11-03 22:00:10 +00:00
2010-02-21 07:45:31 +00:00
/**
2017-06-25 16:02:54 +00:00
* Logical And
2010-02-21 07:45:31 +00:00
*/
2022-06-04 15:31:21 +00:00
public function bitwise_and ( BigInteger $x ) : BigInteger
2010-02-21 07:45:31 +00:00
{
2017-06-25 16:02:54 +00:00
return new static ( $this -> value -> bitwise_and ( $x -> value ));
2009-11-03 22:00:10 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Logical Or
2009-11-03 22:00:10 +00:00
*/
2022-06-04 15:31:21 +00:00
public function bitwise_or ( BigInteger $x ) : BigInteger
2009-11-03 22:00:10 +00:00
{
2017-06-25 16:02:54 +00:00
return new static ( $this -> value -> bitwise_or ( $x -> value ));
}
2009-11-03 22:00:10 +00:00
2017-06-25 16:02:54 +00:00
/**
2018-03-03 12:07:14 +00:00
* Logical Exclusive Or
2017-06-25 16:02:54 +00:00
*/
2022-06-04 15:31:21 +00:00
public function bitwise_xor ( BigInteger $x ) : BigInteger
2017-06-25 16:02:54 +00:00
{
return new static ( $this -> value -> bitwise_xor ( $x -> value ));
2009-11-03 22:00:10 +00:00
}
2007-07-02 04:19:55 +00:00
/**
2017-06-25 16:02:54 +00:00
* Logical Right Shift
2007-07-02 04:19:55 +00:00
*
2017-06-25 16:02:54 +00:00
* Shifts BigInteger ' s by $shift bits , effectively dividing by 2 ** $shift .
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
public function bitwise_rightShift ( int $shift ) : BigInteger
2007-07-02 04:19:55 +00:00
{
2017-06-25 16:02:54 +00:00
return new static ( $this -> value -> bitwise_rightShift ( $shift ));
2007-07-02 04:19:55 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Logical Left Shift
2007-07-02 04:19:55 +00:00
*
2017-06-25 16:02:54 +00:00
* Shifts BigInteger ' s by $shift bits , effectively multiplying by 2 ** $shift .
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
public function bitwise_leftShift ( int $shift ) : BigInteger
2007-07-02 04:19:55 +00:00
{
2017-06-25 16:02:54 +00:00
return new static ( $this -> value -> bitwise_leftShift ( $shift ));
2007-07-02 04:19:55 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Logical Left Rotate
2007-07-02 04:19:55 +00:00
*
2017-06-25 16:02:54 +00:00
* Instead of the top x bits being dropped they ' re appended to the shifted bit string .
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
public function bitwise_leftRotate ( int $shift ) : BigInteger
2007-07-02 04:19:55 +00:00
{
2017-06-25 16:02:54 +00:00
return new static ( $this -> value -> bitwise_leftRotate ( $shift ));
2007-07-02 04:19:55 +00:00
}
2009-12-31 06:11:07 +00:00
/**
2017-06-25 16:02:54 +00:00
* Logical Right Rotate
2009-12-31 06:11:07 +00:00
*
2017-06-25 16:02:54 +00:00
* Instead of the bottom x bits being dropped they ' re prepended to the shifted bit string .
2009-12-31 06:11:07 +00:00
*/
2022-06-04 15:31:21 +00:00
public function bitwise_rightRotate ( int $shift ) : BigInteger
2009-12-31 06:11:07 +00:00
{
2017-06-25 16:02:54 +00:00
return new static ( $this -> value -> bitwise_rightRotate ( $shift ));
2009-12-31 06:11:07 +00:00
}
2007-07-02 04:19:55 +00:00
/**
2017-06-25 16:02:54 +00:00
* Returns the smallest and largest n - bit number
2007-07-02 04:19:55 +00:00
*
2017-12-04 10:11:43 +00:00
* @ return BigInteger []
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
public static function minMaxBits ( int $bits ) : array
2007-07-02 04:19:55 +00:00
{
2018-12-02 16:41:24 +00:00
self :: initialize_static_variables ();
2017-06-25 16:02:54 +00:00
$class = self :: $mainEngine ;
extract ( $class :: minMaxBits ( $bits ));
2017-12-04 10:11:43 +00:00
/** @ var BigInteger $min
2022-02-17 02:25:59 +00:00
* @ var BigInteger $max
2017-12-04 10:11:43 +00:00
*/
2017-06-25 16:02:54 +00:00
return [
'min' => new static ( $min ),
2022-07-23 02:45:53 +00:00
'max' => new static ( $max ),
2017-06-25 16:02:54 +00:00
];
2007-07-02 04:19:55 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Return the size of a BigInteger in bits
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
public function getLength () : int
2007-07-02 04:19:55 +00:00
{
2017-06-25 16:02:54 +00:00
return $this -> value -> getLength ();
2007-07-02 04:19:55 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Return the size of a BigInteger in bytes
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
public function getLengthInBytes () : int
2007-07-02 04:19:55 +00:00
{
2017-06-25 16:02:54 +00:00
return $this -> value -> getLengthInBytes ();
2007-07-02 04:19:55 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Generates a random number of a certain size
2007-07-02 04:19:55 +00:00
*
2017-06-25 16:02:54 +00:00
* Bit length is equal to $size
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
public static function random ( int $size ) : BigInteger
2007-07-02 04:19:55 +00:00
{
2018-12-02 16:41:24 +00:00
self :: initialize_static_variables ();
2017-06-25 16:02:54 +00:00
$class = self :: $mainEngine ;
return new static ( $class :: random ( $size ));
2007-07-02 04:19:55 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Generates a random prime number of a certain size
2007-07-02 04:19:55 +00:00
*
2017-06-25 16:02:54 +00:00
* Bit length is equal to $size
2007-07-02 04:19:55 +00:00
*/
2022-06-04 15:31:21 +00:00
public static function randomPrime ( int $size ) : BigInteger
2007-07-02 04:19:55 +00:00
{
2018-12-02 16:41:24 +00:00
self :: initialize_static_variables ();
2017-06-25 16:02:54 +00:00
$class = self :: $mainEngine ;
return new static ( $class :: randomPrime ( $size ));
2007-07-02 04:19:55 +00:00
}
2012-08-26 06:36:34 +00:00
2014-04-23 21:57:20 +00:00
/**
2017-06-25 16:02:54 +00:00
* Generate a random prime number between a range
2014-04-23 21:57:20 +00:00
*
2017-06-25 16:02:54 +00:00
* If there ' s not a prime within the given range , false will be returned .
2014-05-05 16:34:45 +00:00
*
2017-10-25 09:44:14 +00:00
* @ return false | BigInteger
2014-04-23 21:57:20 +00:00
*/
2017-06-25 16:02:54 +00:00
public static function randomRangePrime ( BigInteger $min , BigInteger $max )
2014-04-23 21:57:20 +00:00
{
2017-06-25 16:02:54 +00:00
$class = self :: $mainEngine ;
return new static ( $class :: randomRangePrime ( $min -> value , $max -> value ));
2014-04-23 21:57:20 +00:00
}
2016-07-31 20:15:48 +00:00
/**
2017-06-25 16:02:54 +00:00
* Generate a random number between a range
2016-07-31 20:15:48 +00:00
*
2017-06-25 16:02:54 +00:00
* Returns a random number between $min and $max where $min and $max
* can be defined using one of the two methods :
2016-07-31 20:15:48 +00:00
*
2017-06-25 16:02:54 +00:00
* BigInteger :: randomRange ( $min , $max )
* BigInteger :: randomRange ( $max , $min )
2016-07-31 20:15:48 +00:00
*/
2022-06-04 15:31:21 +00:00
public static function randomRange ( BigInteger $min , BigInteger $max ) : BigInteger
2016-07-31 20:15:48 +00:00
{
2017-06-25 16:02:54 +00:00
$class = self :: $mainEngine ;
return new static ( $class :: randomRange ( $min -> value , $max -> value ));
2016-07-31 20:15:48 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Checks a numer to see if it ' s prime
2016-07-31 20:15:48 +00:00
*
2017-06-25 16:02:54 +00:00
* Assuming the $t parameter is not set , this function has an error rate of 2 **- 80. The main motivation for the
* $t parameter is distributability . BigInteger :: randomPrime () can be distributed across multiple pageloads
* on a website instead of just one .
*
2017-11-05 20:35:27 +00:00
* @ param int | bool $t
2016-07-31 20:15:48 +00:00
*/
2022-06-04 15:31:21 +00:00
public function isPrime ( $t = false ) : bool
2016-07-31 20:15:48 +00:00
{
2017-06-25 16:02:54 +00:00
return $this -> value -> isPrime ( $t );
2016-07-31 20:15:48 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Calculates the nth root of a biginteger .
2016-07-31 20:15:48 +00:00
*
2017-06-25 16:02:54 +00:00
* Returns the nth root of a positive biginteger , where n defaults to 2
*
* @ param int $n optional
2016-07-31 20:15:48 +00:00
*/
2022-06-04 15:31:21 +00:00
public function root ( int $n = 2 ) : BigInteger
2016-07-31 20:15:48 +00:00
{
2017-06-25 16:02:54 +00:00
return new static ( $this -> value -> root ( $n ));
2016-07-31 20:15:48 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Performs exponentiation .
2016-07-31 20:15:48 +00:00
*/
2022-06-04 15:31:21 +00:00
public function pow ( BigInteger $n ) : BigInteger
2016-07-31 20:15:48 +00:00
{
2017-06-25 16:02:54 +00:00
return new static ( $this -> value -> pow ( $n -> value ));
2016-07-31 20:15:48 +00:00
}
2016-10-19 12:45:42 +00:00
/**
2017-06-25 16:02:54 +00:00
* Return the minimum BigInteger between an arbitrary number of BigIntegers .
2016-10-19 12:45:42 +00:00
*/
2022-06-04 15:31:21 +00:00
public static function min ( BigInteger ... $nums ) : BigInteger
2016-10-19 12:45:42 +00:00
{
2017-06-25 16:02:54 +00:00
$class = self :: $mainEngine ;
2022-08-11 13:12:15 +00:00
$nums = array_map ( fn ( $num ) => $num -> value , $nums );
2017-06-25 16:02:54 +00:00
return new static ( $class :: min ( ... $nums ));
2016-10-19 12:45:42 +00:00
}
/**
2017-06-25 16:02:54 +00:00
* Return the maximum BigInteger between an arbitrary number of BigIntegers .
2016-10-19 12:45:42 +00:00
*/
2022-06-04 15:31:21 +00:00
public static function max ( BigInteger ... $nums ) : BigInteger
2016-10-19 12:45:42 +00:00
{
2017-06-25 16:02:54 +00:00
$class = self :: $mainEngine ;
2022-08-11 13:12:15 +00:00
$nums = array_map ( fn ( $num ) => $num -> value , $nums );
2017-06-25 16:02:54 +00:00
return new static ( $class :: max ( ... $nums ));
2016-10-19 12:45:42 +00:00
}
2016-12-23 16:02:07 +00:00
/**
* Tests BigInteger to see if it is between two integers , inclusive
*/
2022-06-04 15:31:21 +00:00
public function between ( BigInteger $min , BigInteger $max ) : bool
2017-06-25 16:02:54 +00:00
{
return $this -> value -> between ( $min -> value , $max -> value );
}
/**
* Clone
*/
public function __clone ()
2016-12-23 16:02:07 +00:00
{
2017-06-25 16:02:54 +00:00
$this -> value = clone $this -> value ;
2016-12-23 16:02:07 +00:00
}
2018-10-25 01:00:37 +00:00
/**
* Is Odd ?
*/
2022-06-04 15:31:21 +00:00
public function isOdd () : bool
2018-10-25 01:00:37 +00:00
{
return $this -> value -> isOdd ();
}
/**
* Tests if a bit is set
*/
2022-06-04 15:31:21 +00:00
public function testBit ( int $x ) : bool
2018-10-25 01:00:37 +00:00
{
return $this -> value -> testBit ( $x );
}
/**
* Is Negative ?
*/
2022-06-04 15:31:21 +00:00
public function isNegative () : bool
2018-10-25 01:00:37 +00:00
{
return $this -> value -> isNegative ();
}
/**
* Negate
*
* Given $k , returns - $k
*/
2022-06-04 15:31:21 +00:00
public function negate () : BigInteger
2018-10-25 01:00:37 +00:00
{
return new static ( $this -> value -> negate ());
}
/**
* Scan for 1 and right shift by that amount
*
* ie . $s = gmp_scan1 ( $n , 0 ) and $r = gmp_div_q ( $n , gmp_pow ( gmp_init ( '2' ), $s ));
*/
2022-06-04 15:31:21 +00:00
public static function scan1divide ( BigInteger $r ) : int
2018-10-25 01:00:37 +00:00
{
$class = self :: $mainEngine ;
return $class :: scan1divide ( $r -> value );
}
/**
* Create Recurring Modulo Function
*
* Sometimes it may be desirable to do repeated modulos with the same number outside of
* modular exponentiation
*
* @ return callable
*/
public function createRecurringModuloFunction ()
{
$func = $this -> value -> createRecurringModuloFunction ();
2022-08-11 13:12:15 +00:00
return fn ( BigInteger $x ) => new static ( $func ( $x -> value ));
2018-10-25 01:00:37 +00:00
}
/**
* Bitwise Split
*
* Splits BigInteger ' s into chunks of $split bits
*
2022-02-22 00:56:19 +00:00
* @ return BigInteger []
2018-10-25 01:00:37 +00:00
*/
2022-06-04 15:31:21 +00:00
public function bitwise_split ( int $split ) : array
2018-10-25 01:00:37 +00:00
{
2022-08-11 13:12:15 +00:00
return array_map ( fn ( $val ) => new static ( $val ), $this -> value -> bitwise_split ( $split ));
2018-10-25 01:00:37 +00:00
}
2023-02-27 11:34:33 +00:00
}