random()实际上是如何工作的?

时间:2009-08-31 20:41:48

标签: random

每种语言都有random()函数或类似的东西来生成伪随机数。我想知道下面会发生什么来生成这些数字?我不是在编写任何使这些知识成为必要的东西,只是为了满足自己的好奇心。

7 个答案:

答案 0 :(得分:12)

唐纳德克努特的第一章开篇  工作Seminumerical Algorithms涉及随机数生成的主题。我真的不认为SO答案会接近描述所涉及的问题。读这本书。

答案 1 :(得分:4)

Wikipedia page是一个很好的参考。

使用的实际算法将取决于语言和语言的实现。

答案 2 :(得分:4)

事实证明,获得中途正确的伪随机数非常容易。几十年来,黄金标准是一个非常简单的算法:保持状态 x ,乘以常数 A (32x32 => 64位)然后加上常数 B ,然后返回低32位,这也成为新的 x 。如果仔细选择 A B ,这实际上效果很好。

伪随机数也需要是可重复的,以便在调试期间重现行为。因此,在调试期间通常会避免为生成器播种(初始化 x ,比如说,时间)。

近年来,随着更多可用于刻录的计算周期,可以使用更复杂的算法,其中一些算法是在其他非常权威的 Seminumerical Algorithms 出版后发明的。操作系统也开始提供硬件和网络派生的熵位,用于专门的加密目的。

答案 3 :(得分:3)

random()是所谓的伪随机数发生器(PRNG)。 random()主要实现为线性同余生成器。这是X(n + 1)(aXn + c)模m的形式的函数。 Xn是生成的伪随机数的序列。生成的数字序列很容易猜到。该算法不能用作加密安全的PRNG。

Wikipedia:Linear congruential generator

看看PRNG的死硬测试 PRNG Diehard Tests

答案 4 :(得分:0)

要准确回答你的回答,随机功能由操作系统提供(通常)。

但是操作系统如何创建这个随机数是计算机科学中的一个专门领域。例如,参见上面答案中发布的维基页面。

答案 5 :(得分:0)

您可能想要检查的一件事是在Linux和Mac OSX等类Unix操作系统上可用的随机设备系列。例如,在Linux上,内核将来自各种源的熵聚集到一个池中,然后它用来为它的伪随机数生成器播种。熵可以来自各种来源,最值得注意的是来自按键,网络事件,硬盘活动和(最重要的)鼠标移动的设备驱动程序抖动。除此之外,还有其他技术来收集熵,其中一些甚至完全在硬件中实现。有两个字符设备可以从Linux获取随机字节,它们的行为方式如下:

  • / dev / urandom为您提供了一个恒定的字节流,这个字节流非常随机但不具有加密安全性,因为它重用了池中可用的任何熵。
  • / dev / random为您提供加密安全的随机数,但它不会为您提供恒定的流,因为它使用池中可用的熵,然后在收集更多熵时阻塞。

请注意,虽然Mac OSX使用不同的PRNG方法,因此不会阻止,但我的个人基准测试(在大学里完成)表明它的随机性略低于Linux内核。当然,当然还不错。

所以,在我的项目中,当我需要随机性时,我通常会从其中一个随机设备中读取数据,至少是我程序中算法的种子。

答案 6 :(得分:0)

伪随机数生成器 (PRNG),也称为确定性随机位生成器 (DRBG),1 是一种生成数字序列的算法,其属性近似于随机数序列的属性。 PRNG 生成的序列并不是真正随机的,因为它完全由一个初始值决定,称为 PRNG 的种子(可能包括真正的随机值)。尽管可以使用硬件随机数生成器生成更接近于真正随机的序列,但伪随机数生成器在实践中非常重要,因为它们的生成速度和可重复性。[2]

PRNG 在模拟(例如用于蒙特卡罗方法)、电子游戏(例如用于程序生成)和密码学等应用中处于核心地位。密码应用要求输出不能从早期的输出中预测出来,并且需要更复杂的算法,这些算法不继承更简单的 PRNG 的线性。

良好的统计特性是 PRNG 输出的核心要求。通常,需要仔细的数学分析才能确信 PRNG 生成的数字足够接近随机数以适合预期用途。约翰·冯·诺依曼 (John von Neumann) 告诫人们将 PRNG 误解为真正的随机生成器,并开玩笑说“任何考虑使用算术方法生成随机数字的人,当然都处于犯罪状态。”[3]

您可以查看维基百科页面了解更多here