问题 可重现的随机数系列


如何在PHP中获得一系列可重现的伪随机数?

在旧版本的PHP中,我可以通过使用相同的种子来实现 RNG,但它不再起作用,因为PHP改变了rand和mt_rand的工作方式。

请在PHP.net页面中看到此评论:

请记住默认情况下安装的Suhosin补丁   许多PHP安装,如Debian和DirectAdmin完全禁用   srand和mt_srand函数用于加密安全性原因。至   从一个固定的种子生成可重现的随机数   Suhosin强化服务器,您需要包含自己的伪随机数   发电机代码。

该评论的链接: http://www.php.net/manual/en/function.srand.php#102636

准备好了吗?我没有时间也没有经验来创建我自己的伪随机生成器代码。

我的目标是拥有一个代码

<?php
   //( pseudo random code here...)
   $the_seed = 123; // 123 is just a number for demo purposes, NOT a static number
                    //...i hope you get the idea. It's just a hardcoded seed,
                    // it could be a seed based on a user-id, a date etc...
                    // we need the same output for a given seed.
   //( pseudo random code here...)

   // ...and finally
   echo $the_random_number;
 ?>

所以每次我访问这个页面我都会得到相同的号码。


1220
2017-11-09 17:53


起源

刚设置 $the_random_number 到9。 - CanSpice
42会更好。 - Paul Croarkin
你说'每次我访问这个页面我应该得到相同的号码'。这与静态有什么不同? - Paul Croarkin
@PaulCroarkin不同之处在于,他不需要存储数百,数千或数百万件 - 它们可以在运行中生成。他只对从prng返回的第一个数字不感兴趣,他有兴趣拥有许多数字而不必存储它们。 - Adam Davis
@CanSpice应该链接到 XKCD 而是剥离。 - Adam Davis


答案:


Mersenne Twist是一个很好的快速PRNG,这里是一个公共域PHP实现:

http://kingfisher.nfshost.com/sw/twister/

这仅适用于PHP 5.3.0及更高版本。


10
2017-11-09 17:58



先生,谢谢你,我现在就试试吧......我能尽快接受答案:) - Sharky
@Sharky很高兴帮忙。 - Adam Davis
还想为PHP <5.3.0添加此实现 boxrefuge.com/?p=18  (刚刚发现它并测试它就像一个魅力 - 也是一篇关于性能的有趣文章,请查看) - Sharky
@Sharky我在答案中包括了 - 感谢链接! - Adam Davis
@McKay问题的第二段回答了你的问题。简而言之,对于给定的输入,他需要相同的随机数序列 - 这通常通过每次使用相同的种子为随机数生成器播种来实现。但是,PHP的通用安全修补程序删除了为随机数生成器设定种子的能力,因为有太多人将其用于加密应用程序,但未使用加密安全种子源。 - Adam Davis


Mersenne Twister是一些最好的随机数算法之一。 你可以找到一个纯PHP版本 这里 (还有其他人)。

然后你可以打电话:

init_with_integer($integer_seed)

并且每次都获得相同的输出(对于给定的种子)。


7
2017-11-09 18:02



感谢Charles的回答! - Sharky
Dang,Adam Davis是 快速。 - Charles Burns
真奇怪。我想知道为什么我被投票了。 - Charles Burns
我会请你纠正这个:)你不应该因打字速度而受到惩罚 - talkol
谢谢,Talkol :) - Charles Burns


这不是最好的,但它是一个工作

function ranseed($min, $max, $seed) {
    return round($min + (hexdec(md5($seed)) / hexdec("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")) * ($max - $min));
}

-1
2018-02-08 07:09