我有一个使用 php 的 mt_rand() 生成不同随机整数的项目,但我最近可以访问真正的随机位流。我无法弄清楚如何创建一个类似于 mt_rand() 的函数,我可以从我的位流中获取两个值之间的随机整数。我怎样才能做到这一点?
我只会读取PHP_INT_SIZE * 8
位并将结果数字压缩到您需要的范围内:
function squash($nr, $min, $max)
{
return $min + $nr % ($max - $min);
}
另一种方式:
function squash($nr, $min, $max)
{
return $min + round($nr / PHP_INT_MAX * ($max - $min));
}
我刚刚想到,为什么不直接使用您的随机流并将其推送到mt_srand()
:
function squash($nr, $min, $max)
{
mt_srand($nr);
return mt_rand($min, $max);
}
我想出了一个方法,但不确定就使用的位而言,它是否是最有效的方法(代码未经测试,只是演示理论):
function RandomInteger($min, $max)
{
$range = ($max - $min) + 1;
$bitsNeeded = ceil( log($range, 2) );
$number = ReadBitsAndConvertToInteger($bitsNeeded);
if ($number < $range)
return $number + $min;
else if ($number > $range)
return RandomInteger($min, $max);
}
如您所见,该函数有可能被重复,这意味着将使用更多的位,这就是为什么我不确定就使用的位而言,这是否是最有效的方法。
Pr(repeat) = (2^bitsNeeded - range) / (2^bitsNeeded)
Therefore, 0 < Pr(repeat) < 0.5
因此,在最坏的情况下,重复的几率几乎是 0.5,它开始变得不太可能需要重复超过 10 次左右,平均不到 2 次。显然,在不得不重复的几率较低的情况下,这些数字会降低。