Пример #1
0
 /**
  * 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));
 }
Пример #2
0
 /**
  * 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));
 }