如何在不将生成器植入PHP的情况下如何获得可预测的伪随机数序列?

问题描述

| host0ѭ和
mt_srand()
在我的主机服务器上被禁用。我想从数组中选择一些随机项目,但在特定的一天应该相同。带日期的种子可以在我的计算机上工作,但不能在主机服务器上工作。 (该死的这些让残疾人开心的安全偏执狂!) 外部生成器会很好,但是我似乎找不到任何生成器。我不是在做密码学,而是最基本的随机性。 编辑:完成。我在一个相关的问题中找到了这个简单的版本,并为PHP修改代码。完善!     

解决方法

        如果确实需要基本的随机性,则可以使用MD5之类的东西从可预测的字符串(例如,所讨论的日期)中生成哈希。 抓取前8个字符,转换为十进制,然后除以可能的最大值(
16 ^ 8 - 1 = 4294967295
),然后获得0到1之间的伪随机值。
$seed = date(\'ymd\',$theDate);
$hash = md5($seed); // eg: a9993e364706816aba3e25717850c26c

$num = hexdec(substr($hash,4)) / 4294967295; // 2845392438 / 4294967295 = 0.662494

$myRandomItem = $myArray[floor($num * count($myArray))];
如果您需要选择多个项目,则可以简单地移至接下来的8个字符,或者向种子添加一个可预测的递增值:
for ($i = 0; $i < $numOfThingsINeed; ++$i) {
    $seed = date(\'ymd\',$theDate) . $i;
    // etc
}
    ,        该网站www.random.org具有良好的随机生成器(对于某些用途是免费的)。对于额外的味道,甚至来自大气噪声也可以是“真正的随机”。我了解您需要在一天中保持一致,但是您可以轻松地解决此问题,方法是保存站点中的一组数字并全天使用它们……当然,如果系统允许的话。此解决方案取决于很多因素(列表的大小),但是如果每天下载一个新的随机数序列,则不会出现外部站点的带宽问题。 编辑:该站点是相当可靠的,但它偶尔会停机,因此我建议存储几天的随机数。 经过澄清后,Edit2: 如果简单的方法就足够了,为什么不编写自己的伪随机数生成器呢?如果密码学并不重要,则可以使用任何一种简单的算法,例如:http://en.wikipedia.org/wiki/Mersenne_twister,本文甚至提供了伪代码实现。