15

我正在寻找一种使用 PHP生成大随机数的方法,例如:

mt_rand($lower, $upper);

我看到的是gmp_random () 但它不允许我只指定每个肢体的位数的下限和上限(我不知道它是什么)。

编辑:Axsuuls 的答案似乎与我想要的非常接近,并且与 gmp_random 非常相似,但是在一种情况下似乎只有一个缺陷。

假设我不想得到一个随机数:

  • 1225468798745475454898787465154

和:

  • 1225468798745475454898787465200

所以如果函数调用BigRandomNumber ():

BigRandomNumber($length = 31);

这可以轻松返回超出指定边界的 9999999999999999999999999999999。

如何使用最小/最大边界而不是长度值?

BigRandomNumber('1225468798745475454898787465154', '1225468798745475454898787465200');

这应该返回一个介于1225468798745475454898787465 [154 .. 200]之间的随机数。

作为参考,我认为解决方案可能必须使用此问题中提供的功能

编辑:上面的帖子被删除了,这里是:

function compare($number1, $operator, $number2) {
  $x = bccomp($number1, $number2);

  switch($operator) {
    case '<':
      return -1===$x;
    case '>':
      return 1===$x;
    case '=':
    case '==':
    case '===':
      return 0===$x;
    case '!=':
    case '!==':
    case '<>':
      return 0!==$x;
  }
}
4

14 回答 14

16

尝试以下操作:

function BigRandomNumber($min, $max) {
  $difference   = bcadd(bcsub($max,$min),1);
  $rand_percent = bcdiv(mt_rand(), mt_getrandmax(), 8); // 0 - 1.0
  return bcadd($min, bcmul($difference, $rand_percent, 8), 0);
}

数学如下:将最小值和最大值之间的差乘以随机百分比,然后加上最小值(四舍五入为 int)。

于 2009-10-01T15:31:09.403 回答
6

你真正需要知道的是相对差距;如果它很小,那么您可以生成一个从 0 到最大间隙的数字,然后添加最小值。

于 2009-10-03T03:58:16.173 回答
2

这将为您的巨型随机数提供更多零,您还可以指定巨型随机数的长度(您的巨型随机数可以以 0 开头吗?如果不是,也可以轻松实现)

<?php

$randNumberLength = 1000;  // length of your giant random number
$randNumber = NULL;

for ($i = 0; $i < $randNumberLength; $i++) {
    $randNumber .= rand(0, 9);  // add random number to growing giant random number

}

echo $randNumber;

?>

祝你好运!

于 2009-09-25T22:51:41.863 回答
1

您可以做的是创建一些较小的随机数并将它们组合起来。不确定你实际需要多大。

于 2009-09-25T22:26:52.990 回答
0
$lower = gmp_com("1225468798745475454898787465154");
$upper = gmp_com("1225468798745475454898787465200");

$range_size = gmp_sub($upper, $lower);

$rand = gmp_random(31);
$rand = gmp_mod($rand, $range_size);

$result = gmp_add($rand, $lower);

完全未经测试:-)

于 2009-10-01T15:36:52.217 回答
0

这可能对你有用。(我不确定你为什么需要它,所以它可能不是最好的方法,但它应该符合你的要求):

<?php
function bigRandomNumber($min, $max)
{
 // check input first
    if ($max < $min) { return false; }
    // Find max & min length of the number
    $lenMin = strlen ($min);
    $lenMax = strlen ($max);

    // Generate a random length for the random number
    $randLen = $lenMin + mt_rand(0, $lenMax - $lenMin);
    /* Generate the random number digit by digit, 
       comparing it with the min and max values */
 $b_inRange = false;
    for ($i = 0; $i < $randLen; $i++)
 {
  $randDigit = mt_rand(0,9);

  /* As soon as we are sure that the number will stay 
          in range, we can stop comparing it to min and max */
  if (!$b_inRange)
  {
   $tempRand = $rand . $randDigit;
   $tempMin = substr($min, 0, $i+1);
   $tempMax = substr($max, 0, $i+1);
   // Make sure that the temporary random number is in range
   if ($tempRand < $tempMin || $tempRand > $tempMax)
   {
    $lastDigitMin = substr($tempMin, -1);
    $lastDigitMax = substr($tempMax, -1);
    $tempRand = $rand . @mt_rand($lastDigitMin, $lastDigitMax);
   }
   /* Check if $tempRand is equal to the min or to the max value. 
               If it is not equal, then we know it will stay in range */
   if ($tempRand > $tempMin && $tempRand < $tempMax)
   {
    $b_inRange = true;
   }
  }
  else
  {
   $tempRand = $rand . $randDigit;
  }
  $rand = $tempRand;  
 }
 return $rand;
}

我尝试了几次,看起来它工作正常。如果需要,进行优化。这个想法是首先为您的随机数计算一个随机长度,使其处于可接受的范围内。然后通过连接生成随机数字,直到该长度。如果不在范围内,则在范围内生成一个新的随机数字并连接。

我使用 PHP 将字符串转换为数字这一事实来利用字符串函数。当然,这会为 mt_rand 生成一个警告,但由于我们只使用数字,所以应该安全地抑制它。

现在,我不得不说我很好奇你为什么首先需要这个。

于 2009-10-03T08:04:25.807 回答
0
/* Inputs: 
 * min - GMP number or string: lower bound
 * max - GMP number or string: upper bound
 * limiter - GMP number or string: how much randomness to use.
 *  this value is quite obscure (see `gmp_random`, but the default
 *  supplies several hundred bits of randomness, 
 *  which is probably enough.
 * Output: A random number between min (inclusive) and max (exclusive).
*/
function BigRandomNumber($min, $max, $limiter = 20) {
  $range = gmp_sub($max, $min);
  $random = gmp_random();
  $random = gmp_mod($random, $range);
  $random = gmp_add($min, $random);
  return $random;
}

这只是rand_range($min, $max) = $min + rand() % ($max - $min)转换为任意精度算术的经典公式。如果不是 2 的幂,它可能会表现出一定量的偏差$max - $min,但如果与偏差的大小相比,随机性的位数足够高,$max - $min则可以忽略不计。

于 2009-10-03T10:49:18.310 回答
0

这可能有效:

  • 将数字拆分为包含 9 个或更少数字(“其余”)的数组 ... 9 个字符,因为我的机器上的最大 rand 数为 2147483647。
  • 对于每个“9 或更少的数字数组块”,创建一个随机数。
  • 内爆数组,您现在将拥有一个可用的随机数。

说明这个想法的示例代码(注意:代码已撤消)

function BigRandomNumber($min,$max) {
// Notice: Will only work when both numbers have same length.
echo (strlen($min) !== strlen($max)) ? "Error: Min and Max numbers must have same length" : NULL;
$min_arr = str_split($min);
$max_arr = str_split($max);
// TODO: This loop needs to operate on 9 chars ($i will increment by $i+9)
for($i=0; $i<=count($max_arr); $i++) {
    if($i == 0) {
        // First number: >=first($min) and <=first($max).
        $new_arr[$i] = rand( $min_arr[0], $max_arr[0]);
    } else if($i == count($max_arr)) {
        // Last number <= $max .. not entirely correct, feel free to correct it.
        $new_arr[$i] = rand(0, substr($max,-1));
    } else {
        $new_arr[$i] = rand(0,9);
    }
}
return implode($new_arr);
}
于 2009-10-03T17:01:29.407 回答
0

测试和工作

<?php 

$min = "1225468798745475454898787465154";
$max = "1225468798745475454898787465200";

$bigRandNum = bigRandomNumber($min,$max);
echo "The Big Random Number is: ".$bigRandNum."<br />";

function bigRandomNumber($min,$max) {
    // take the max number length
    $number_length = strlen($max);

    // Set the counter
    $i = 1;

    // Find the base and the min and max ranges
    // Loop through the min to find the base number
    while ($i <= $number_length) {
        $sub_string = substr($min, 0, $i);

        // format pattern
        $format_pattern = '/'.$sub_string.'/';
        if (!preg_match($format_pattern, $max)) {
            $base = $sub_string;

            // Set the min and max ranges
            $minRange = substr($min, ($i - 1), $number_length);
            $maxRange = substr($max, ($i - 1), $number_length);

            // End while loop, we found the base
            $i = $number_length;
        }
        $i++;
    }
    // find a random number with the min and max range
    $rand = rand($minRange, $maxRange);

    // add the base number to the random number
    $randWithBase = $base.$rand;

    return $randWithBase;
}

?>
于 2009-10-05T12:54:31.830 回答
0

生成“n”个随机字符并不是一个真正的选择,因为 random('9999999999') 在理论上仍然可以返回 1...

这是一个非常简单的函数:

function bcrand($max) { 
    return bcmul($max, (string)mt_rand() / mt_getrandmax() ); 
}

请注意,它不会返回 N 位随机性,只需调整比例

于 2013-03-09T02:25:58.493 回答
0

大整数的范围是 1-20。所以生成一个数字mt_rand($lower, $upper)并与另一个相乘mt_rand($lower, $upper)

$N1=mt_rand($lower, $upper);
$N2=mt_rand($lower, $upper);
$N3=$N1*N2;

注意:n 位与 n 位相乘得到 n*2 位。

于 2020-02-07T11:10:21.753 回答
0

这个问题就像十年前一样被问到,但对于来自谷歌的人来说,propper 答案是 gmp_random_range("min_value", "max_value") 函数。

$range=gmp_random_range("1225468798745475454898787465154", "1225468798745475454898787465200");
echo gmp_strval($range); // displays value as string
于 2020-04-08T02:03:07.097 回答
-1

拿你的地板和你的随机数在它的范围内。

1225468798745475454898787465154 + rand(0, 6)
于 2009-10-01T15:43:54.780 回答
-1

这是伪代码:


// generate a random number between N1 and N2

rangesize = N2 - N1 + 1
randlen = length(rangesize) + 4 // the 4 is to get more digits to reduce bias
temp = BigRandomNumber(randlen) // generate random number, "randlen" digits long
temp = temp mod rangesize
output N1 + temp

笔记:

  • 这里的所有算术(第二行除外)都必须是任意精度:为此使用 bcmath 库
  • 在第二行中,“长度”是位数,因此 1025 的“长度”将为 4
于 2009-10-03T03:39:36.157 回答