伪随机数生成器

14

如何创建最好的伪随机数生成器?(任何语言都可以)


这是一个重要的研究领域,目前还没有确定最佳度量标准...你想要实现什么目标? - dmckee --- ex-moderator kitten
你想要真正的随机性还是想要可以重复的类似随机的序列? - Robert Gould
@Robert Gould:他已经指定了伪随机。如果他正在寻找真正的随机性,那么他确实是在错误的道路上咆哮... - dmckee --- ex-moderator kitten
从即将被删除的答案中:硬件随机数生成器 - Jayan
12个回答

25

避免创建伪随机数生成器是最好的方法。

伪随机数生成器 是一个非常复杂的主题,因此最好使用由深入了解该主题的人们制作的实现。


12
我下投反对票是因为“不要重复制造轮子”是一个糟糕的回答,尤其是由无能的程序员不断传播。永远不应该被告知不要做某事。 - Krythic
4
我同意@Krythic的评论。你不应该打击一个人或初学者,告诉他们这太复杂了。这会阻止学习过程,是错误的。-1 - Box Box Box Box
由于某种原因,这种类型的回答让我很烦恼,如果初学者真的想把它作为练习来实现,那么不要阻止他们这样做。类似于初学者问“如何实现HTML解析器作为练习”之前,人们说“使用beautifulsoup”。同意@Krythic的观点。 - user14520680
1
@expressjs123 我现在正在重新发明轮子,制作一个颜色选择器。可能已经有现成的颜色选择器可以使用,但我想自己动手做。重新发明轮子是学习新知识的方式,我永远不会告诉任何人不要这样做。这是我的项目图片:https://imgur.com/a/A6hnv8F - Krythic

13

一切都取决于应用程序。例如,生成“最随机”数字的发生器可能不是最快或最节省内存的。

Mersenne Twister算法是一种流行的、相当快速的伪随机数生成器,产生相当好的结果。它有一个极其庞大的周期,但也有一个相对庞大的状态(2.5 kB)。然而,它被认为不足以用于加密应用。

更新: 自本回答撰写以来,PCG算法族已发布,似乎在大多数方面(速度、内存、随机性和周期)优于现有的非加密算法,使其成为除了密码学之外的绝佳选择。

如果您正在进行加密处理,我的回答仍然是:不要自己动手。


机器翻译还有一个优点,就是对于大的n,可以在n*[0-1)空间上均匀地绘制n元组,而不是每个伪随机数生成器都能做到这一点。这是它在许多领域的蒙特卡罗研究中非常受欢迎的原因之一。 - dmckee --- ex-moderator kitten
"it is not deemed good enough for cryptographic applications": 不,MT 在密码学中是绝对禁止使用的,因为从 MT 的 624 个输出数序列可以预测其整个未来输出!捕获适当的密码随机数生成器的输出序列不会提供有关其未来输出的任何信息。 - kquinn
3
"捕获正确密码学随机数生成器的输出序列并不能提供有关其未来输出的任何信息。"这是错误的,信息仍然存在。只是未来输出需要计算难度非常大。" - starblue

7
德国杂志C't在2009年第2期中测试了许多软件和硬件生成器,并通过各种统计测试来运行结果。我在这里扫描了结果。我不会费力地编写自己的生成器。文章提到,即使是唐纳德·克努斯(Donald Knuth)也未能成功使用他的“超级随机数生成器”,它实际上并不那么随机。获取一个通过所有测试的生成器(在所有列中都有结果> 0)。他们还测试了使用具有硬件RNG的VIA EPIA M10000主板的设置。我喜欢这个选项,适用于需要高吞吐量的强大随机数服务器的商业或半商业设置。当然,除非你只是玩玩,否则这个可能已经足够好了。

1
硬件随机数生成器不适合用于需要PRNG的情况,即需要可重复输出的情况,这对于模拟使用非常重要。 - Joey

4

PRNG算法很复杂,获取正确的熵源使其良好运作也是如此。这不是你想自己做的事情。每种现代语言都有一个几乎肯定适合你使用的PRNG库。

xkcd random number


3
哎呀,这个可以变得非常复杂!似乎有许多衡量“随机性”的随机数生成器指标,因此很难确定哪些是“最佳”的。我建议从Numerical Recipes in C(或其他语言的类似书籍)中了解一些示例。我根据那里提供的示例编写了我的第一个简单的随机数生成器。
编辑:确定你需要多复杂的随机数生成器也很重要。我记得几��前在C语言中遇到的一个令人不快的问题是,默认的随机数生成器周期大约为32,767,这意味着在生成那么多数字后它往往会周期性地重复自己!如果你只需要几次掷骰子,那就没问题。但如果你需要为模拟生成数百万个“随机”值,那就不行了。

2
数值计算法是一个危险的领域,因为他们不允许您在未为每个用户购买许可证的情况下使用代码。这是我们在大学仿真框架中遇到的一个陷阱,造成了很大的麻烦。对于C语言的随机数生成器而言,周期通常约为2^32,它只发出15位。 - Joey

2

1
请点击此链接查看TestU01测试套件,其中包含了多个测试模块。

http://www.iro.umontreal.ca/~simardr/testu01/tu01.html

在这篇论文中,作者展示了对多种现有随机数生成器的测试结果,但好像没有包括 .NET System.Random。不过他确实测试了 VB6 的生成器。
很少有随机数生成器能通过所有测试...

0

抄袭Knuth seminumeric的一个算法。 高质量且易于实现。 它使用一对数组、加法和几个条件语句。 便宜、有效,并且长周期美好,如果我没记错的话是2^55。


我模糊地记得一本著名书籍中的随机数生成器非常糟糕,但由于它在一本著名书籍中被使用而广泛使用。不过我现在找不到任何相关信息了。这可能是另一本书。在您将其用于任何关键目的之前,请务必进行检查。 - Thomas

0
如果你要在C++中工作,Boost有一系列的伪随机数生成器,我会比标准库更信任它们。文档可能会对你挑选一个合适的PRNG有所帮助。总的来说,一个好的PRNG取决于你使用它的目的。

0

你不能直接添加一个指向某个代码库的链接。这个代码库可能会在某个时间点被弃用,人们将无法得到解决问题的方法。相反,应该解释一下如何解决提问者所遇到的问题。 - Abhishek Dutt
1
好的,我的建议是:如果你不是该领域的专家,请不要自己创建“PRNG”。使用现有的库,例如Numpy中的PRNG。 - sosei

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接