由于计算机不能随机选择数字(难道它们可以吗?),那么这个随机数是如何生成的呢?例如在C#中,我们说:
Random.Next()
里面会发生什么?
由于计算机不能随机选择数字(难道它们可以吗?),那么这个随机数是如何生成的呢?例如在C#中,我们说:
Random.Next()
里面会发生什么?
您可以查看这篇文章。根据文档,.NET中使用的特定实现基于Donald E. Knuth的减法伪随机数生成算法。有关更多信息,请参见D. E. Knuth。《计算机程序设计艺术 第2卷:半数值算法》。Addison-Wesley,Reading,MA,第二版,1981年。
.NET加密类具有适用于加密或涉及资金的游戏的随机数的方法。至于它们的工作原理:关于加密强度的随机性的文献非常广泛;有关详细信息,请参阅任何一本好的大学本科密码学教材。
还存在专门硬件以获取随机位。如果您需要从大气噪声中抽取的随机数,请参见www.random.org。
尽管如此,每个数字都在同步翻转,这使得它变得可预测。如果您获得两个连续的值,它们是相关的,因此如果您绘制它们,您将在屏幕上获得线条。现在想象一下,您有结合生成器的规则,使得连续的值不是下一个值。 例如
v1 = rand1() >> 8 ^ rand2() ... v2 = rand2() >> 8 ^ rand5() ..
并且想象种子不总是会前进。现在,您正在开始制作一些更难以基于反向工程预测的东西,并且序列更长。
例如,如果您每次计算rand1(),但仅在第3次时才推进rand2()中的种子,则组合它们的生成器可能不会重复超过任何一个周期。
现在想象一下,您将(相当可预测的)模数类型随机数生成器通过DES或其他加密算法进行处理。那将混淆位。
显然,有更好的算法,但这可以给你一个想法。Numerical Recipes实现了很多算法并加以解释。一个非常好的技巧是:在表中生成一组随机值而不是一个。然后使用独立的随机数生成器来选择其中一个生成的数字,生成一个新的数字并替换它。这样可以打破相邻数字之间的任何相关性。http://www.random.org/randomness/
根据当前的科学,这是真正的随机。也许有一天我们会发现它遵循某些基本规则,但目前,我们无法预测这些值,对我们来说它们是“真正”的随机。
如果您想查看一些源代码,Boost库具有出色的C ++ Fibonacci生成器实现,这是伪随机序列的统治者。
Random.Next()
如何工作)无关。Random
类是一个伪随机数生成器。
它基本上是一个极长但确定性的重复序列。 "随机性" 来自于不同的起始位置。指定起始位置是通过为随机数生成器选择种子来完成的,例如可以使用系统时间或从另一个随机源获取随机种子。默认的 Random 构造函数使用系统时间作为种子。
用于生成数字序列的实际算法在MSDN中有文档记录:
当前 Random 类的实现基于 Donald E. Knuth 的减法随机数生成器算法。有关更多信息,请参见 D. E. Knuth。《计算机程序设计艺术,卷 2:半数值算法》。Addison-Wesley,Reading,MA,第二版,1981年。
计算机使用伪随机数生成器。它们的工作原理是从一个种子数字开始,并通过算法迭代每次需要新的伪随机数。
这个过程当然是完全确定性的,因此给定的种子每次使用时都会生成完全相同的数字序列,但生成的数字形成了统计上均匀分布(大约),这是可以接受的,因为在大多数情况下,你只需要随机性。
通常的做法是使用当前系统时间作为种子,但如果需要更高的安全性,则可以从物理源(如磁盘延迟)中收集“熵”以生成更难预测的种子。在这种情况下,您还需要使用密码学强随机数生成器,例如this。
我不知道太多细节,但我知道的是种子用于生成随机数,然后基于某些算法使用该种子获得新数字。
如果您基于相同的种子获取随机数,则它们通常会相同。