是161803398“特殊”号码? Math.Random()内部
我怀疑答案是“ 因为math ”,但我希望有人能够在基本层面上多一点洞察力。
我今天在BCL源代码中探索一下,看看我之前使用过的一些类是如何实现的。 我从来没有想过如何生成(伪)随机数,所以我决定看看它是如何完成的。
完整源代码在这里: http : //referencesource.microsoft.com/#mscorlib/system/random.cs#29
private const int MSEED = 161803398;
每次使用Random()类时,都会使用此MSEED值。
无论如何,我看到这个“神奇的数字” – 161803398 – 我不知道为什么这个数字被选中。 这不是一个素数或二的权力。这不是一个数字的“一半”,似乎更重要。 我用二进制和hex来查看它,它对我来说只是一个数字。
我试图在Googlesearch这个号码,但是我什么也没find。
不,但它是基于披(“黄金比例”)。
161803398 = 1.61803398 * 10^8 ≈ φ * 10^8
更多关于黄金比例在这里 。
对于这个偶然的math家来说,这是一个很好的阅读 。
而且我发现了一个关于随机数发生器的研究论文 ,这个论断同意这个观点。 (请参阅第53页。)
这个数字取自黄金比例 1.61803398 * 10 ^ 8 。 马特给出了一个很好的答案,这个数字是什么,因此我只是稍微解释一下algorithm。
这个algorithm不是一个特殊的数字。 该algorithm是Knuth的减法随机数生成器algorithm ,其要点是:
- 存储56个随机数字的循环列表
- 初始化是填充列表的过程,然后用特定的确定性algorithm随机化这些值
- 两个指数保持相隔31
- 新的随机数是这两个指数的两个值的差异
- 将新的随机数存储在列表中
生成器基于以下recursion:X n =(X n-55 – X n-24 )mod m,其中n&geq; 0.这是滞后斐波那契发生器的一个部分情况:X n =(X nj @ X nk )mod m,其中0 <k <j和@是任何二进制运算(相减,加法,异或)。
这个发生器有几个实现。 Knuth在他的书中提供了FORTRAN的一个实现。 我发现下面的代码 ,有以下注释:
参数(MBIG = 1000000000,MSEED = 161803398,MZ = 0,FAC = 1.E-9)
根据Knuth的说法,任何大型MBIG,以及任何较小(但仍然很大)的MSEED都可以替代上述值。
可以在这里find一点点注意,这实际上并不是一篇研究论文(如math所述),这只是一个硕士学位论文。
密码学中的人们喜欢使用无理数( pi
, e
, sqrt(5)
),因为有这样的猜想,即这些数字的数字以相同的频率出现,因此具有高熵 。 你可以在security stackexchange上find这个相关的问题来了解更多关于这个数字的信息。 这是一个报价:
“如果常数是随机select的,那么很有可能没有攻击者能够破坏它。” 但是,当一个有些人说:“让我们使用这个常量吧,我随机选了他们,我发誓 ” ,但是密码学家却是一个多疑的人。 所以作为一个妥协,他们会使用常量,比如π的二进制扩展。 虽然我们不再有从一大堆数字中随意select它们的math优势,但我们至less可以更有信心没有破坏。