保存/恢复PHP的rand()的状态

时间:2013-02-25 04:12:42

标签: php random

为了防止在长时间运行的预渲染脚本中出现内存损坏,我希望能够对我的程序说“好了,渲染前1000个步骤”。然后我可以看一下输出,检查它等等。然后我想说“现在生成步骤1,001到10,000”。

我的工作几乎完美。我正在努力解决一件事。

渲染脚本使用rand()将熵添加到生成的输出中,并在开始时使用srand()以确保它在重新渲染中保持不变。目前我通过计算调用rand()的次数来“解决”这个问题,然后在开始实际生成之前多次调用它。问题在于它可能非常慢,特别是当我生成了几百万个随机数时。

有没有办法确定我需要传递给srand()以继续生成序列的值?这甚至可能吗?

如果没有,有没有办法找出确切的算法rand()正在使用什么?我真的很喜欢我从srand(43)获得的地图,并希望尽可能保留它!


编辑:使用Patashu的答案,这就是我的想法:

function rnd() {
    static $seed = 42;
    $seed = $seed*214013+2531011;
    $mod = pow(2,32);
    while($seed > $mod) $seed -= $mod;
    $rs = floor($seed/65536)&0x7fff;
    return floor(2*$rs/0x8000);
}

它依赖于浮点数的使用,因为据我所知,尾数的51位很容易以完美的精度存储数字,如果使用位运算符,则整数会被截断或环绕。

2 个答案:

答案 0 :(得分:2)

这不是直接回答你的问题,但由于看起来你不需要特别“好”的随机数,为什么不考虑编写你自己的伪随机数发生器?这样,您可以在需要时轻松地序列化和反序列化其状态。

http://en.wikipedia.org/wiki/Random_number_generation#Computational_methods处的算法甚至可以做到这一点。无论何时开始新序列,都可以使用当前时间播种。

答案 1 :(得分:1)

此页面http://cod.ifies.com/2008/05/php-rand01-on-windows-openssl-rand-on.html解释了PHP的rand()

的源代码

请注意,它不是很漂亮,它依赖于PHP的怪癖和rand()的操作系统实现:)