/** * Generate a random number * * @param optional Integer $min * @param optional Integer $max * @return BigInteger * @access public */ function random($min = false, $max = false) { if ($min === false) { $min = new BigInteger(0); } if ($max === false) { $max = new BigInteger(0x7fffffff); } $compare = $max->compare($min); if (!$compare) { return $this->_normalize($min); } else { if ($compare < 0) { // if $min is bigger then $max, swap $min and $max $temp = $max; $max = $min; $min = $temp; } } $generator = $this->generator; $max = $max->subtract($min); $max = ltrim($max->toBytes(), chr(0)); $size = strlen($max) - 1; $random = ''; $bytes = $size & 1; for ($i = 0; $i < $bytes; ++$i) { $random .= chr($generator(0, 255)); } $blocks = $size >> 1; for ($i = 0; $i < $blocks; ++$i) { // mt_rand(-2147483648, 0x7FFFFFFF) always produces -2147483648 on some systems $random .= pack('n', $generator(0, 0xffff)); } $temp = new BigInteger($random, 256); if ($temp->compare(new BigInteger(substr($max, 1), 256)) > 0) { $random = chr($generator(0, ord($max[0]) - 1)) . $random; } else { $random = chr($generator(0, ord($max[0]))) . $random; } $random = new BigInteger($random, 256); return $this->_normalize($random->add($min)); }
/** * Generate a random number * * @param optional Integer $min * @param optional Integer $max * @return Math_BigInteger * @access public */ function random($min = false, $max = false) { if ($min === false) { $min = new BigInteger(0); } if ($max === false) { $max = new BigInteger(0x7fffffff); } $compare = $max->compare($min); if (!$compare) { return $this->_normalize($min); } else { if ($compare < 0) { // if $min is bigger then $max, swap $min and $max $temp = $max; $max = $min; $min = $temp; } } $max = $max->subtract($min); $max = ltrim($max->toBytes(), chr(0)); $size = strlen($max) - 1; $crypt_random = function_exists('crypt_random_string') || !class_exists('Crypt_Random') && function_exists('crypt_random_string'); if ($crypt_random) { $random = crypt_random_string($size); } else { $random = ''; if ($size & 1) { $random .= chr(mt_rand(0, 255)); } $blocks = $size >> 1; for ($i = 0; $i < $blocks; ++$i) { // mt_rand(-2147483648, 0x7FFFFFFF) always produces -2147483648 on some systems $random .= pack('n', mt_rand(0, 0xffff)); } } $fragment = new BigInteger($random, 256); $leading = $fragment->compare(new BigInteger(substr($max, 1), 256)) > 0 ? ord($max[0]) - 1 : ord($max[0]); if (!$crypt_random) { $msb = chr(mt_rand(0, $leading)); } else { $cutoff = floor(0xff / $leading) * $leading; while (true) { $msb = ord(crypt_random_string(1)); if ($msb <= $cutoff) { $msb %= $leading; break; } } $msb = chr($msb); } $random = new BigInteger($msb . $random, 256); return $this->_normalize($random->add($min)); }