它会扔硬币来获得随机位吗? 还是掷骰子来获得1到6之间的随机整数? 还是从经过打乱的牌组中拿出一张卡片来获得1到52之间的数字? 。 。 。 还是可以像我们一样思考或拥有像我们一样的智慧?显然,以上示例不是生成随机数据的方法。那么,软件库如何在给定范围内生成random数字?哪个更随机:由人还是软件生成? 最佳答案 (注意:这通常是关于计算及其用途中的随机[和伪随机]数。)确定性的过程永远都不可能有真正的随机数,这就是为什么计算机不太适合生成随机数的原因(因为CPU只能以确定性的方式翻转位)。大多数语言,框架和库都使用所谓的Pseudo-random number generators(PRNG)。那些采用某种初始状态向量的种子,该初始状态向量可以是单个数字或数字数组,并从那里生成一系列看似随机的值。结果通常满足某些统计指标,但并非完全随机,因为同一种子将产生完全相同的序列。最简单的PRNG之一是所谓的Linear Congruential Generator(LCG)。它只有一个数字作为状态(最初是种子)。然后,对于每个连续的返回值,公式将像这样循环:其中a,b和c是生成器的常数。 c通常是2的幂,例如232,仅仅是因为它易于实现(自动完成)且速度很快。但是,很难找到a和b的好值。作为最简单的示例,当使用a = 2和b = 0时,您可以看到结果值永远不会是奇数。这限制了发生器可以非常严格地产生的值的范围。通常,LCG是一个非常古老的概念,长期以来被更好的生成器所取代,因此,除非在极其有限的环境中使用(除非即使嵌入式系统通常也可以毫无问题地处理更好的生成器),否则不要使用它们-MT19937或其概括, WELL generators通常对于只不想担心其伪随机数的属性的人来说要好得多。PRNG的一项主要应用是仿真。由于PRNG可以估计或保证统计特性,并且由于种子的性质可以精确地重复进行实验,因此它们在这里做得很好。假设您要发表论文,并希望其他人复制您的结果。使用硬件RNG(如下所述),除了包含您使用的每个单个随机数之外,您别无选择。对于可以轻松使用数十亿个甚至更多个数字的蒙特卡洛模拟,这是不可行的。然后是用于密码应用的随机数生成器,例如保护您的SSL连接。例如Windows的CryptGenRandom或Unix的/dev/urandom。这些通常也是PRNG,但是它们使用所谓的“熵池”进行播种,其中包含不可预测的值。这里的要点是生成不可预测的序列,即使相同的种子仍会产生相同的序列。为了最大程度地减少攻击者猜测序列的影响,需要定期对它们进行重新播种。熵池是从系统中的各个点收集的:事件,例如输入,网络活动等。有时,它也会被初始化为整个系统中假定包含垃圾的内存位置。但是,如果完成,必须注意确保熵池确实包含不可预测的内容。 Something that Debian got wrong in OpenSSL a few years ago.您也可以直接使用熵池来获取随机数(例如,Linux的/dev/random; FreeBSD对/dev/random使用与/dev/urandom相同的算法),但是一次也不会得到太多它是空的,需要一段时间才能补充。这就是为什么上面提到的算法通常用于将很小的熵扩展到更大的体积的原因。然后是基于硬件的随机数生成器,它们使用不可预测的自然过程,例如放射性衰变或电线中的电噪声。那些是最苛刻的应用程序,需要许多“真正的”随机数,并且通常每秒可以生成数百MiB的随机性(好吧,该数据点已有几年历史,但是我怀疑这样做可以做很多)现在更快)。您可以通过编写一个程序来模拟这样的事情,该程序是从带镜头盖的网络摄像头拍摄图像(然后才保留噪点),或者从不存在实际输入的音频输入中获取图像。那些对于一点黑客来说是很好的,但是通常不会产生良好的随机数,因为它们有偏差,即在比特流中零和那些比特没有以相同的频率表示(或者更进一步,序列00,,01和10的生成频率不同...您也可以对较大的序列执行此操作)。因此,实际硬件RNG的一部分用于确保结果值满足某些统计分布属性。有些人actually throw dice to get random dice rolls甚至take this into overdrive。人类创造了very bad random number generators。
08-04 09:45