随机数生成器如何工作?


23

我只是在考虑php rand()函数,并思考如何重新制作它,于是我完全呆呆了。

随机数生成器如何工作?


2
伪随机数生成器使用种子,预定义常数表和数学公式。真正的随机数发生器通常使用大气噪声。您可以通过读取/ dev / random轻松获得随机数。
2011年

大气噪声是否保证是随机的?


14
function rand() { return 4; /* determined by die roll - guaranteed to be random */ }
尼尔

3
有人必须这样做:xkcd.com/221 ;)
Valera Kolupaev 2011年

Answers:


7

随机数生成器(RNG)实际上正在生成伪随机数,因为实际上不可能生成TRULY随机数。唯一真正真正随机的事物是上帝的行为,例如闪电。

这篇Wikipedia文章可能会帮助您进行解释:http : //en.wikipedia.org/wiki/Random_number_generators


据我了解,RNG基本上有两个部分:种子,然后是从该种子中选择的随机数。当您为RNG植入种子时,您将其等同于起点。然后,该起点具有一堆数字,这些数字位于程序选择的“内部”。在PHP中,可以使用srand()来“混洗”种子,因此几乎总是可以得到不同的答案。然后,您可以使用rand(min,max)进入种子,并选择介于min和max之间的一个数字。


警告,可能会出现类似奶酪的情况!

将每个“种子”想象成一个冰柜,然后将随机数想象成一个冰块。假设您有1000个冰柜,每个箱子内有1000个冰块。在县集市上,他们将选择一个冰柜开始饮用,他们只能使用一个冰块。但是,他们只需要大于1立方英寸的冰块。因此,他们将在这1000个箱子中随机选择一个箱子,然后在该箱子中随机选择一个冰块。如果它适合他们想要的大小,则使用它。如果不是,他们会与其他人放回胸部。如果他们想让它变得更有趣,那么他们会事先改变箱子以便完全忘却!

至于PHP实际上是如何实际选择种子和随机数的,我对此没有足够的了解(这可能是您最想知道的!)。我不会尝试重做rand()函数;对于您要制作的大多数基于Web的应用程序,rand()应该足以满足您需要的任何随机数。

另外,请检查线性同余生成器,如果您想要脏的详细信息,这可能是您正在寻找的更多内容:http : //en.wikipedia.org/wiki/Linear_congruential_generator

希望这可以帮助!


7
god最小的行为将如何随机?最重要的是,闪电也不是随机的,它遵循由各种条件决定的路径。同样,生成数字的解释器本质上是不相关的。

7
我使用的是法律意义上的上帝行为:en.wikipedia.org/wiki/Act_of_God 它们被认为是随机的,因为它们超出了人类的明显控制。

4
因此,从本质上讲,没有什么是随机的。但这将影响到每一个看似随机的事件,当您刚开始时这是行不通的。...看来我要上一些哲学课= D

6
据我们所知,@ Korvin的量子现象,例如放射性衰变或被激发原子发射的光子,实际上是随机的。但是,数学家和哲学家确实争论了真正随机的意义。而且,尽管普通人认为抛硬币是随机的,但敏捷的舞台魔术师(news.stanford.edu/pr/2004/diaconis-69.html)可以在10次翻转中得到10 个正面。
查尔斯E.格兰特

1
@Charles-投掷硬币甚至不是二进制的正反面,实际上是正反面,所以真正好的舞台魔术师可以使它既不掉头也不掉尾。* 8')
Mark Booth

18

它们通常不是真正随机的,而是称为伪随机的,因为它们生成的数字序列看起来是随机的。这是通过一些有趣的数学公式完成的。最常见的一种是线性同余生成器

伪随机数确实具有一个真正的随机数没有的有用属性:如果在启动时使用相同的种子,则会返回相同的序列。这对于测试可能非常方便。


如果我正确理解了您的第二句话:random(5332)将始终等于random(5332)

2
@Korvin,不,我的意思是如果您拨打电话,srand(5332)那么下一个返回的数字rand将始终相同。
Mark Ransom

3
“出现随机”->具有与真正随机数相同的统计属性。

+1的LGC维基百科的链接,这具有优良的动画为什么做multidimansional蒙特卡罗模拟时simplt的PRNG具有很大的局限性。
Mark Booth,

4

您是要求伪随机还是随机?其他人回答了关于伪随机的问题,让我谈谈随机性。

有(出售)基于硬件的实际随机数发生器。它们基于带有小型无线电的芯片,该芯片可测量深空辐射的白噪声,或具有小型放射性样品并测量其衰减之间的周期。它们的问题是带宽-它们可以产生的熵的数量不是很高,因此它们被用作伪随机算法的种子。它们被用于银行系统,高安全性等。

OTOH,如果您遇到任何嵌入式系统开发人员,他们都会为您嘲笑。出于对微控制器进行编程的常见目的,读取任何16位模数转换器的低4位,而该引脚的浮动(未连接)引脚会产生非常好的随机噪声,且带宽要大于足够的带宽(轮询周期越短,“噪音”),比编写实际的RNG例程要容易。考虑到ADC通常在微控制器芯片中实现,通常实现,并且通常通过8个通道实现,因此您的应用程序可能需要5个通道,这实际上是免费的。

即使没有ADC,连接到数字GPIO引脚的几个元件也会产生相当好的噪声。在嵌入式系统中,噪声一直存在(并且一直在奋斗),因此获得一些真正的随机性非常容易。


2

有许多方法可以尝试模拟数字的“随机”序列。当然,您的第一站应该是阅读线性同余生成器。这是大多数基本随机数生成器的工作方式,我敢打赌,这就是PHP的rand()函数的工作方式。

接下来要思考的一个有趣问题是它如何播种自身?时间?IP地址?等等


种子使我感到困惑,我想不出任何可以在没有某种模式的情况下为函数提供种子的东西,即使没有,也首先导致了随机种子的产生!

3
我相信,当实际上没有从其他来源提供时间戳时,通常会将时间戳用作初始种子。在旧的BASIC中,这RANDOMIZE TIMER是一个常见的习惯用法,对于大多数(非加密)目的来说“足够好”。根据man 3 srand的说法,GNU C库使用固定的1种子,直到PRNG重新播种。
的CVn

1

首先,几乎所有rand()函数都不提供真正的随机性,而是提供所谓的伪随机数。

那么,伪随机数生成器如何工作?基本上以与加密工作相同的方式进行操作:您有一个函数(一个散列),该函数接受一些输入,并以一种复杂的方式产生一些输出,使得输出无法猜测输入,反之亦然。也就是说,每个密码都可用于创建一个相当不错的伪随机数生成器。但是,虽然原则上可以使用任何伪随机数生成器进行加密,但是大多数伪随机数生成器主要是为了提高速度而不是加密安全性而开发的,因此它们不会给黑客带来任何麻烦。

对于伪随机生成器,将哈希函数应用于生成器的某些隐藏内部状态,并且其输出用于a)修改该内部状态,以及b)计算函数的输出rand()。的下一次调用rand()将使用更改后的内部状态,从而产生不同的结果。哈希函数越好,则将结果与真实随机数区分开的可能性就越小。


实际上,当今的计算机可以访问实际的随机数:它们是由外部设备产生的中断时间的抖动引起的。Linux使用这些不确定性较小的值来不断搅动一个“熵池”,该熵池只有几千字节的内部状态。可通过/dev/random/dev/urandom设备使用基于此熵池的加密哈希。因此,访问一些真正非常好的随机数就像打开这两个设备之一并从其中读取一些字节一样简单。


-2

随机数是由进程生成的数字,其输出不可预测。即我们无法确定下一个输出将是什么。我们可以举一些简单的骰子结果示例。当我们扔骰子时将要输出的东西是无法预测的。

随机数有两种类型。1.真随机数2.伪随机数。

如何生成随机数


1
请使用引号格式突出显示答案的哪些部分属于您,哪些是您引用的来源。如果您的答案只是来自外部来源的复制/粘贴,则此处不是一个好答案。

这似乎并没有提供任何实质性的制作上分和6分之前解释的答案
蚊蚋
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.