如何从位流中获取两个值之间的整数


How to get integer between two values from stream of bits?

我有一个使用 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 次。显然,在不得不重复的几率较低的情况下,这些数字会降低。