includes/math.php
changeset 1227 bdac73ed481e
parent 1081 745200a9cc2a
child 1380 0e400f946644
equal deleted inserted replaced
1226:de56132c008d 1227:bdac73ed481e
    16  * EnanoMath GMP backend
    16  * EnanoMath GMP backend
    17  */
    17  */
    18 
    18 
    19 class EnanoMath_GMP
    19 class EnanoMath_GMP
    20 {
    20 {
    21   var $api = 'GMP';
    21 	var $api = 'GMP';
    22   
    22 	
    23   /**
    23 	/**
    24    * Initializes a number to a GMP integer.
    24  	* Initializes a number to a GMP integer.
    25    * @param string String representation of the number
    25  	* @param string String representation of the number
    26    * @param int Base the number is currently in, defaults to 10
    26  	* @param int Base the number is currently in, defaults to 10
    27    * @return resource
    27  	* @return resource
    28    */
    28  	*/
    29   
    29 	
    30   function init($int, $base = 10)
    30 	function init($int, $base = 10)
    31   {
    31 	{
    32     return ( is_resource($int) ) ? $int : gmp_init($int, $base);
    32 		return ( is_resource($int) ) ? $int : gmp_init($int, $base);
    33   }
    33 	}
    34   
    34 	
    35   /**
    35 	/**
    36    * Converts a number from a GMP integer to a string
    36  	* Converts a number from a GMP integer to a string
    37    * @param resource
    37  	* @param resource
    38    * @param int Base, default is 10
    38  	* @param int Base, default is 10
    39    * @return string
    39  	* @return string
    40    */
    40  	*/
    41   
    41 	
    42   function str($int, $base = 10)
    42 	function str($int, $base = 10)
    43   {
    43 	{
    44     return ( is_string($int) ) ? $int : gmp_strval($int, $base);
    44 		return ( is_string($int) ) ? $int : gmp_strval($int, $base);
    45   }
    45 	}
    46   
    46 	
    47   /**
    47 	/**
    48    * Converts a number between bases.
    48  	* Converts a number between bases.
    49    * @param resource BigInt to convert
    49  	* @param resource BigInt to convert
    50    * @param int Base to convert from
    50  	* @param int Base to convert from
    51    * @param int Base to convert to
    51  	* @param int Base to convert to
    52    */
    52  	*/
    53    
    53  	
    54   function basecon($int, $from, $to)
    54 	function basecon($int, $from, $to)
    55   {
    55 	{
    56     return $this->init(gmp_strval(gmp_init($this->str($int), $from), $to));
    56 		return $this->init(gmp_strval(gmp_init($this->str($int), $from), $to));
    57   }
    57 	}
    58   
    58 	
    59   /**
    59 	/**
    60    * Generates a random integer.
    60  	* Generates a random integer.
    61    * @param int Length
    61  	* @param int Length
    62    * @return resource
    62  	* @return resource
    63    */
    63  	*/
    64   
    64 	
    65   function random($len)
    65 	function random($len)
    66   {
    66 	{
    67     return gmp_random($len / 8);
    67 		return gmp_random($len / 8);
    68   }
    68 	}
    69   
    69 	
    70   /**
    70 	/**
    71    * Powmod operation (calculates (a ^ b) mod m)
    71  	* Powmod operation (calculates (a ^ b) mod m)
    72    * @param resource a
    72  	* @param resource a
    73    * @param resource b
    73  	* @param resource b
    74    * @param resource m
    74  	* @param resource m
    75    * @return resource
    75  	* @return resource
    76    */
    76  	*/
    77   
    77 	
    78   function powmod($a, $b, $m)
    78 	function powmod($a, $b, $m)
    79   {
    79 	{
    80     $a = $this->init($a);
    80 		$a = $this->init($a);
    81     $b = $this->init($b);
    81 		$b = $this->init($b);
    82     $m = $this->init($m);
    82 		$m = $this->init($m);
    83     return ( function_exists('gmp_powm') ) ? gmp_powm($a, $b, $m) : gmp_mod(gmp_pow($a, $b), $m);
    83 		return ( function_exists('gmp_powm') ) ? gmp_powm($a, $b, $m) : gmp_mod(gmp_pow($a, $b), $m);
    84   }
    84 	}
    85 }
    85 }
    86 
    86 
    87 /**
    87 /**
    88  * EnanoMath big_int backend
    88  * EnanoMath big_int backend
    89  */
    89  */
    90 
    90 
    91 class EnanoMath_BigInt
    91 class EnanoMath_BigInt
    92 {
    92 {
    93   var $api = 'big_int';
    93 	var $api = 'big_int';
    94   
    94 	
    95   /**
    95 	/**
    96    * Initializes a number to a BigInt integer.
    96  	* Initializes a number to a BigInt integer.
    97    * @param string String representation of the number
    97  	* @param string String representation of the number
    98    * @param int Base the number is in, defaults to 10
    98  	* @param int Base the number is in, defaults to 10
    99    * @return resource
    99  	* @return resource
   100    */
   100  	*/
   101   
   101 	
   102   function init($int, $base = 10)
   102 	function init($int, $base = 10)
   103   {
   103 	{
   104     return (is_resource($int)) ? $int : bi_from_str($int, $base);
   104 		return (is_resource($int)) ? $int : bi_from_str($int, $base);
   105   }
   105 	}
   106   
   106 	
   107   /**
   107 	/**
   108    * Converts a number from a BigInt integer to a string
   108  	* Converts a number from a BigInt integer to a string
   109    * @param resource
   109  	* @param resource
   110    * @param int Base, default is 10
   110  	* @param int Base, default is 10
   111    * @return string
   111  	* @return string
   112    */
   112  	*/
   113   
   113 	
   114   function str($int, $base = 10)
   114 	function str($int, $base = 10)
   115   {
   115 	{
   116     return ( is_string($int) ) ? $int : bi_to_str($int, $base);
   116 		return ( is_string($int) ) ? $int : bi_to_str($int, $base);
   117   }
   117 	}
   118   
   118 	
   119   /**
   119 	/**
   120    * Generates a random integer
   120  	* Generates a random integer
   121    * @param int Length (bits)
   121  	* @param int Length (bits)
   122    * @return resource
   122  	* @return resource
   123    */
   123  	*/
   124   
   124 	
   125   function random($len)
   125 	function random($len)
   126   {
   126 	{
   127     return bi_rand($len);
   127 		return bi_rand($len);
   128   }
   128 	}
   129   
   129 	
   130   /**
   130 	/**
   131    * Converts a number between bases.
   131  	* Converts a number between bases.
   132    * @param resource BigInt to convert
   132  	* @param resource BigInt to convert
   133    * @param int Base to convert from
   133  	* @param int Base to convert from
   134    * @param int Base to convert to
   134  	* @param int Base to convert to
   135    */
   135  	*/
   136   
   136 	
   137   function basecon($int, $from, $to)
   137 	function basecon($int, $from, $to)
   138   {
   138 	{
   139     return bi_base_convert($this->str($int, $from), $from, $to);
   139 		return bi_base_convert($this->str($int, $from), $from, $to);
   140   }
   140 	}
   141   
   141 	
   142   /**
   142 	/**
   143    * Powmod operation (calculates (a ^ b) mod m)
   143  	* Powmod operation (calculates (a ^ b) mod m)
   144    * @param resource a
   144  	* @param resource a
   145    * @param resource b
   145  	* @param resource b
   146    * @param resource m
   146  	* @param resource m
   147    * @return resource
   147  	* @return resource
   148    */
   148  	*/
   149   
   149 	
   150   function powmod($a, $b, $m)
   150 	function powmod($a, $b, $m)
   151   {
   151 	{
   152     $a = $this->init($a);
   152 		$a = $this->init($a);
   153     $b = $this->init($b);
   153 		$b = $this->init($b);
   154     $m = $this->init($m);
   154 		$m = $this->init($m);
   155     return bi_powmod($a, $b, $m);
   155 		return bi_powmod($a, $b, $m);
   156   }
   156 	}
   157 }
   157 }
   158 
   158 
   159 /**
   159 /**
   160  * EnanoMath BCMath backend
   160  * EnanoMath BCMath backend
   161  */
   161  */
   162 
   162 
   163 class EnanoMath_BCMath
   163 class EnanoMath_BCMath
   164 {
   164 {
   165   var $api = 'BCMath';
   165 	var $api = 'BCMath';
   166   
   166 	
   167   /**
   167 	/**
   168    * Initializes a number to a BCMath integer.
   168  	* Initializes a number to a BCMath integer.
   169    * @param string String representation of the number
   169  	* @param string String representation of the number
   170    * @param int Base the number is in, defaults to 10
   170  	* @param int Base the number is in, defaults to 10
   171    * @return resource
   171  	* @return resource
   172    */
   172  	*/
   173   
   173 	
   174   function init($int, $base = 10)
   174 	function init($int, $base = 10)
   175   {
   175 	{
   176     return $this->basecon($int, $base, 10);
   176 		return $this->basecon($int, $base, 10);
   177   }
   177 	}
   178   
   178 	
   179   /**
   179 	/**
   180    * Converts a number from a BCMath integer to a string
   180  	* Converts a number from a BCMath integer to a string
   181    * @param resource
   181  	* @param resource
   182    * @param int Base, default is 10
   182  	* @param int Base, default is 10
   183    * @return string
   183  	* @return string
   184    */
   184  	*/
   185    
   185  	
   186   function str($res)
   186 	function str($res)
   187   {
   187 	{
   188     return ( is_string($res) ) ? $res : strval($this->basecon($res, 10, $base));
   188 		return ( is_string($res) ) ? $res : strval($this->basecon($res, 10, $base));
   189   }
   189 	}
   190   
   190 	
   191   /**
   191 	/**
   192    * Generates a random integer
   192  	* Generates a random integer
   193    * @param int Length in bits
   193  	* @param int Length in bits
   194    * @return resource
   194  	* @return resource
   195    */
   195  	*/
   196   
   196 	
   197   function random($len)
   197 	function random($len)
   198   {
   198 	{
   199     $len = 4 * $len;
   199 		$len = 4 * $len;
   200     $chars = '0123456789abcdef';
   200 		$chars = '0123456789abcdef';
   201     $ret = '';
   201 		$ret = '';
   202     for ( $i = 0; $i < $len; $i++ )
   202 		for ( $i = 0; $i < $len; $i++ )
   203     {
   203 		{
   204       $chid = mt_rand ( 0, strlen($chars) - 1 );
   204 			$chid = mt_rand ( 0, strlen($chars) - 1 );
   205       $chr = $chars{$chid};
   205 			$chr = $chars{$chid};
   206       $ret .= $chr;
   206 			$ret .= $chr;
   207     }
   207 		}
   208     return $this->basecon($this->init($ret), 16, 10);
   208 		return $this->basecon($this->init($ret), 16, 10);
   209   }
   209 	}
   210   
   210 	
   211   /**
   211 	/**
   212    * Converts a number between bases.
   212  	* Converts a number between bases.
   213    * @param resource BigInt to convert
   213  	* @param resource BigInt to convert
   214    * @param int Base to convert from
   214  	* @param int Base to convert from
   215    * @param int Base to convert to
   215  	* @param int Base to convert to
   216    */
   216  	*/
   217   
   217 	
   218   function basecon($int, $from, $to)
   218 	function basecon($int, $from, $to)
   219   {
   219 	{
   220     if ( $from != 10 )
   220 		if ( $from != 10 )
   221       $int = $this->_bcmath_base2dec($int, $from);
   221 			$int = $this->_bcmath_base2dec($int, $from);
   222     if ( $to != 10 )
   222 		if ( $to != 10 )
   223       $int = $this->_bcmath_dec2base($int, $to);
   223 			$int = $this->_bcmath_dec2base($int, $to);
   224     return $int;
   224 		return $int;
   225   }
   225 	}
   226   
   226 	
   227   /**
   227 	/**
   228    * Powmod operation (calculates (a ^ b) mod m)
   228  	* Powmod operation (calculates (a ^ b) mod m)
   229    * @param resource a
   229  	* @param resource a
   230    * @param resource b
   230  	* @param resource b
   231    * @param resource m
   231  	* @param resource m
   232    * @return resource
   232  	* @return resource
   233    */
   233  	*/
   234   
   234 	
   235   function powmod($a, $b, $m)
   235 	function powmod($a, $b, $m)
   236   {
   236 	{
   237     $a = $this->init($a);
   237 		$a = $this->init($a);
   238     $b = $this->init($b);
   238 		$b = $this->init($b);
   239     $m = $this->init($m);
   239 		$m = $this->init($m);
   240     return ( function_exists('bcpowmod') ) ? bcpowmod($a, $b, $m) : bcmod( bcpow($a, $b), $m );
   240 		return ( function_exists('bcpowmod') ) ? bcpowmod($a, $b, $m) : bcmod( bcpow($a, $b), $m );
   241   }
   241 	}
   242   
   242 	
   243   // from us.php.net/bc:
   243 	// from us.php.net/bc:
   244   // convert a decimal value to any other base value
   244 	// convert a decimal value to any other base value
   245   function _bcmath_dec2base($dec,$base,$digits=FALSE) {
   245 	function _bcmath_dec2base($dec,$base,$digits=FALSE) {
   246       if($base<2 or $base>256) die("Invalid Base: ".$base);
   246 			if($base<2 or $base>256) die("Invalid Base: ".$base);
   247       bcscale(0);
   247 			bcscale(0);
   248       $value="";
   248 			$value="";
   249       if(!$digits) $digits=$this->_bcmath_digits($base);
   249 			if(!$digits) $digits=$this->_bcmath_digits($base);
   250       while($dec>$base-1) {
   250 			while($dec>$base-1) {
   251           $rest=bcmod($dec,$base);
   251 					$rest=bcmod($dec,$base);
   252           $dec=bcdiv($dec,$base);
   252 					$dec=bcdiv($dec,$base);
   253           $value=$digits[$rest].$value;
   253 					$value=$digits[$rest].$value;
   254       }
   254 			}
   255       $value=$digits[intval($dec)].$value;
   255 			$value=$digits[intval($dec)].$value;
   256       return (string) $value;
   256 			return (string) $value;
   257   }
   257 	}
   258   
   258 	
   259   // convert another base value to its decimal value
   259 	// convert another base value to its decimal value
   260   function _bcmath_base2dec($value,$base,$digits=FALSE) {
   260 	function _bcmath_base2dec($value,$base,$digits=FALSE) {
   261       if($base<2 or $base>256) die("Invalid Base: ".$base);
   261 			if($base<2 or $base>256) die("Invalid Base: ".$base);
   262       bcscale(0);
   262 			bcscale(0);
   263       if($base<37) $value=strtolower($value);
   263 			if($base<37) $value=strtolower($value);
   264       if(!$digits) $digits=$this->_bcmath_digits($base);
   264 			if(!$digits) $digits=$this->_bcmath_digits($base);
   265       $size=strlen($value);
   265 			$size=strlen($value);
   266       $dec="0";
   266 			$dec="0";
   267       for($loop=0;$loop<$size;$loop++) {
   267 			for($loop=0;$loop<$size;$loop++) {
   268           $element=strpos($digits,$value[$loop]);
   268 					$element=strpos($digits,$value[$loop]);
   269           $power=bcpow($base,$size-$loop-1);
   269 					$power=bcpow($base,$size-$loop-1);
   270           $dec=bcadd($dec,bcmul($element,$power));
   270 					$dec=bcadd($dec,bcmul($element,$power));
   271       }
   271 			}
   272       return (string) $dec;
   272 			return (string) $dec;
   273   }
   273 	}
   274   
   274 	
   275   function _bcmath_digits($base) {
   275 	function _bcmath_digits($base) {
   276       if($base>64) {
   276 			if($base>64) {
   277           $digits="";
   277 					$digits="";
   278           for($loop=0;$loop<256;$loop++) {
   278 					for($loop=0;$loop<256;$loop++) {
   279               $digits.=chr($loop);
   279 							$digits.=chr($loop);
   280           }
   280 					}
   281       } else {
   281 			} else {
   282           $digits ="0123456789abcdefghijklmnopqrstuvwxyz";
   282 					$digits ="0123456789abcdefghijklmnopqrstuvwxyz";
   283           $digits.="ABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
   283 					$digits.="ABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
   284       }
   284 			}
   285       $digits=substr($digits,0,$base);
   285 			$digits=substr($digits,0,$base);
   286       return (string) $digits;
   286 			return (string) $digits;
   287   }
   287 	}
   288 }
   288 }
   289 
   289 
   290 /**
   290 /**
   291  * Creates a new math object based on what libraries are available.
   291  * Creates a new math object based on what libraries are available.
   292  * @return object
   292  * @return object
   293  */
   293  */
   294 
   294 
   295 function enanomath_create()
   295 function enanomath_create()
   296 {
   296 {
   297   if ( function_exists('gmp_init') )
   297 	if ( function_exists('gmp_init') )
   298     return new EnanoMath_GMP();
   298 		return new EnanoMath_GMP();
   299   else if ( function_exists('bi_from_str') )
   299 	else if ( function_exists('bi_from_str') )
   300     return new EnanoMath_BigInt();
   300 		return new EnanoMath_BigInt();
   301   else if ( function_exists('bcadd') )
   301 	else if ( function_exists('bcadd') )
   302     return new EnanoMath_BCMath();
   302 		return new EnanoMath_BCMath();
   303   else
   303 	else
   304     throw new Exception('dh_err_not_supported');
   304 		throw new Exception('dh_err_not_supported');
   305 }
   305 }
   306 
   306 
   307 ?>
   307 ?>