我只是在考虑php rand()
函数,并思考如何重新制作它,于是我完全呆呆了。
随机数生成器如何工作?
function rand() { return 4; /* determined by die roll - guaranteed to be random */ }
我只是在考虑php rand()
函数,并思考如何重新制作它,于是我完全呆呆了。
随机数生成器如何工作?
function rand() { return 4; /* determined by die roll - guaranteed to be random */ }
Answers:
随机数生成器(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
希望这可以帮助!
它们通常不是真正随机的,而是称为伪随机的,因为它们生成的数字序列看起来是随机的。这是通过一些有趣的数学公式完成的。最常见的一种是线性同余生成器。
伪随机数确实具有一个真正的随机数没有的有用属性:如果在启动时使用相同的种子,则会返回相同的序列。这对于测试可能非常方便。
srand(5332)
那么下一个返回的数字rand
将始终相同。
您是要求伪随机还是随机?其他人回答了关于伪随机的问题,让我谈谈随机性。
有(出售)基于硬件的实际随机数发生器。它们基于带有小型无线电的芯片,该芯片可测量深空辐射的白噪声,或具有小型放射性样品并测量其衰减之间的周期。它们的问题是带宽-它们可以产生的熵的数量不是很高,因此它们被用作伪随机算法的种子。它们被用于银行系统,高安全性等。
OTOH,如果您遇到任何嵌入式系统开发人员,他们都会为您嘲笑。出于对微控制器进行编程的常见目的,读取任何16位模数转换器的低4位,而该引脚的浮动(未连接)引脚会产生非常好的随机噪声,且带宽要大于足够的带宽(轮询周期越短,“噪音”),比编写实际的RNG例程要容易。考虑到ADC通常在微控制器芯片中实现,通常实现,并且通常通过8个通道实现,因此您的应用程序可能需要5个通道,这实际上是免费的。
即使没有ADC,连接到数字GPIO引脚的几个元件也会产生相当好的噪声。在嵌入式系统中,噪声一直存在(并且一直在奋斗),因此获得一些真正的随机性非常容易。
有许多方法可以尝试模拟数字的“随机”序列。当然,您的第一站应该是阅读线性同余生成器。这是大多数基本随机数生成器的工作方式,我敢打赌,这就是PHP的rand()函数的工作方式。
接下来要思考的一个有趣问题是它如何播种自身?时间?IP地址?等等
RANDOMIZE TIMER
是一个常见的习惯用法,对于大多数(非加密)目的来说“足够好”。根据man 3 srand的说法,GNU C库使用固定的1种子,直到PRNG重新播种。
首先,几乎所有rand()
函数都不提供真正的随机性,而是提供所谓的伪随机数。
那么,伪随机数生成器如何工作?基本上以与加密工作相同的方式进行操作:您有一个函数(一个散列),该函数接受一些输入,并以一种复杂的方式产生一些输出,使得输出无法猜测输入,反之亦然。也就是说,每个密码都可用于创建一个相当不错的伪随机数生成器。但是,虽然原则上可以使用任何伪随机数生成器进行加密,但是大多数伪随机数生成器主要是为了提高速度而不是加密安全性而开发的,因此它们不会给黑客带来任何麻烦。
对于伪随机生成器,将哈希函数应用于生成器的某些隐藏内部状态,并且其输出用于a)修改该内部状态,以及b)计算函数的输出rand()
。的下一次调用rand()
将使用更改后的内部状态,从而产生不同的结果。哈希函数越好,则将结果与真实随机数区分开的可能性就越小。
实际上,当今的计算机可以访问实际的随机数:它们是由外部设备产生的中断时间的抖动引起的。Linux使用这些不确定性较小的值来不断搅动一个“熵池”,该熵池只有几千字节的内部状态。可通过/dev/random
和/dev/urandom
设备使用基于此熵池的加密哈希。因此,访问一些真正非常好的随机数就像打开这两个设备之一并从其中读取一些字节一样简单。