File indexing completed on 2024-12-22 05:36:34
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Crypt 0017 * @subpackage Math 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 * @version $Id$ 0021 */ 0022 0023 /** 0024 * @see Zend_Crypt_Math_BigInteger 0025 */ 0026 // require_once 'Zend/Crypt/Math/BigInteger.php'; 0027 0028 /** 0029 * @category Zend 0030 * @package Zend_Crypt 0031 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0032 * @license http://framework.zend.com/license/new-bsd New BSD License 0033 */ 0034 class Zend_Crypt_Math extends Zend_Crypt_Math_BigInteger 0035 { 0036 0037 /** 0038 * Generate a pseudorandom number within the given range. 0039 * Will attempt to read from a systems RNG if it exists or else utilises 0040 * a simple random character to maximum length process. Simplicity 0041 * is a factor better left for development... 0042 * 0043 * @param string|int $minimum 0044 * @param string|int $maximum 0045 * @return string 0046 */ 0047 public function rand($minimum, $maximum) 0048 { 0049 if (file_exists('/dev/urandom')) { 0050 $frandom = fopen('/dev/urandom', 'r'); 0051 if ($frandom !== false) { 0052 return fread($frandom, strlen($maximum) - 1); 0053 } 0054 } 0055 if (strlen($maximum) < 4) { 0056 return mt_rand($minimum, $maximum - 1); 0057 } 0058 $rand = ''; 0059 $i2 = strlen($maximum) - 1; 0060 for ($i = 1; $i < $i2; $i++) { 0061 $rand .= mt_rand(0, 9); 0062 } 0063 $rand .= mt_rand(0, 9); 0064 return $rand; 0065 } 0066 0067 /** 0068 * Return a random strings of $length bytes 0069 * 0070 * @param integer $length 0071 * @param boolean $strong 0072 * @return string 0073 */ 0074 public static function randBytes($length, $strong = false) 0075 { 0076 $length = (int) $length; 0077 if ($length <= 0) { 0078 return false; 0079 } 0080 if (function_exists('random_bytes')) { // available in PHP 7 0081 return random_bytes($length); 0082 } 0083 if (function_exists('mcrypt_create_iv')) { 0084 $bytes = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); 0085 if ($bytes !== false && strlen($bytes) === $length) { 0086 return $bytes; 0087 } 0088 } 0089 if (file_exists('/dev/urandom') && is_readable('/dev/urandom')) { 0090 $frandom = fopen('/dev/urandom', 'r'); 0091 if ($frandom !== false) { 0092 return fread($frandom, $length); 0093 } 0094 } 0095 if (true === $strong) { 0096 // require_once 'Zend/Crypt/Exception.php'; 0097 throw new Zend_Crypt_Exception( 0098 'This PHP environment doesn\'t support secure random number generation. ' . 0099 'Please consider installing the OpenSSL and/or Mcrypt extensions' 0100 ); 0101 } 0102 $rand = ''; 0103 for ($i = 0; $i < $length; $i++) { 0104 $rand .= chr(mt_rand(0, 255)); 0105 } 0106 return $rand; 0107 } 0108 0109 /** 0110 * Return a random integer between $min and $max 0111 * 0112 * @param integer $min 0113 * @param integer $max 0114 * @param boolean $strong 0115 * @return integer 0116 */ 0117 public static function randInteger($min, $max, $strong = false) 0118 { 0119 if ($min > $max) { 0120 // require_once 'Zend/Crypt/Exception.php'; 0121 throw new Zend_Crypt_Exception( 0122 'The min parameter must be lower than max parameter' 0123 ); 0124 } 0125 $range = $max - $min; 0126 if ($range == 0) { 0127 return $max; 0128 } elseif ($range > PHP_INT_MAX || is_float($range)) { 0129 // require_once 'Zend/Crypt/Exception.php'; 0130 throw new Zend_Crypt_Exception( 0131 'The supplied range is too great to generate' 0132 ); 0133 } 0134 if (function_exists('random_int')) { // available in PHP 7 0135 return random_int($min, $max); 0136 } 0137 // calculate number of bits required to store range on this machine 0138 $r = $range; 0139 $bits = 0; 0140 while ($r) { 0141 $bits++; 0142 $r >>= 1; 0143 } 0144 $bits = (int) max($bits, 1); 0145 $bytes = (int) max(ceil($bits / 8), 1); 0146 $filter = (int) ((1 << $bits) - 1); 0147 do { 0148 $rnd = hexdec(bin2hex(self::randBytes($bytes, $strong))); 0149 $rnd &= $filter; 0150 } while ($rnd > $range); 0151 return ($min + $rnd); 0152 } 0153 0154 /** 0155 * Get the big endian two's complement of a given big integer in 0156 * binary notation 0157 * 0158 * @param string $long 0159 * @return string 0160 */ 0161 public function btwoc($long) 0162 { 0163 if (ord($long[0]) > 127) { 0164 return "\x00" . $long; 0165 } 0166 return $long; 0167 } 0168 0169 /** 0170 * Translate a binary form into a big integer string 0171 * 0172 * @param string $binary 0173 * @return string 0174 */ 0175 public function fromBinary($binary) 0176 { 0177 return $this->_math->binaryToInteger($binary); 0178 } 0179 0180 /** 0181 * Translate a big integer string into a binary form 0182 * 0183 * @param string $integer 0184 * @return string 0185 */ 0186 public function toBinary($integer) 0187 { 0188 return $this->_math->integerToBinary($integer); 0189 } 0190 }