Perl 28/13≈2.15
sub r{$s^=~($s^=$s/7215)<<8}
日志文件在这里
Perl 29/13≈2.23
sub r{$s^=~($s^=$s<<8)/60757}
日志文件在这里
这些是Xorshift的变体,使用浮点除法而不是右移。他们都通过了15项测试中的13项,仅通过了6项和7项测试。
我不确定周期有多长,但是由于以下代码不会在任何短时间内终止,因此可能是完整的2 32:
$start = r();
$i++ while $start != r();
print $i;
Perl 39/10 = 3.9
$s=$^T;sub r{~($s=$s*$s%4294969373)||r}
注意:如果您正在寻找Blum-Blum-Shub风格的PRNG,Keith Randall的解决方案将比这两种方案都要好。
与下面的原始解决方案一样,这也是Blum Blum Shub的实现,但有一个主要区别。我使用的模数略大于2 32(M = 50971•84263),并且每当遇到一个值,它不是有效的32位整数(即大于2 32)时,它将返回旋转。从本质上讲,这些值被删减,其余的旋转不受干扰,从而导致几乎均匀的分布。
似乎有所帮助。除了通过与以前相同的9个测试之外,它现在还令人信服地通过了最小距离测试。可以在此处找到示例日志文件。
Perl 33/9≈3.67(无效?)
$s=$^T;sub r{$s=$s*$s%4294951589}
注意:此解决方案可能被认为是无效的,因为永远不会观察到该范围的最高0.00037%。
Blum Blum Shub的快速而肮脏的实现。我声明以下结果:
1. passed - Birthday Spacings
2. FAILED - Overlapping Permutations
3. passed - Ranks of 31x31 and 32x32 Matrices
4. passed - Ranks of 6x8 Matrices
5. FAILED - Monkey Tests on 20-bit Words
6. FAILED - Monkey Tests OPSO, OQSO, DNA
7. FAILED - Count the 1s in a Stream of Bytes
8. passed - Count the 1s for Specific Bytes
9. passed - Parking Lot Test
10. FAILED - Minimum Distance Test
11. passed - Random Spheres Test
12. FAILED - The Squeeze Test
13. passed - Overlapping Sums Test
14. passed - Runs Test
15. passed - The Craps Test
您可以在此处找到示例日志文件,可以随意质疑任何结果。diehard的文件可以通过以下方式生成:
print pack('N', r()) for 1..4194304
然后将输出传递到文件中。最小距离看起来可能已经过去了,但是如果您多次运行它,它总是非常接近1.0,这表明失败了。
细节
通常,Blum Blum Shub是一种糟糕的PRNG,但可以通过选择良好的模量来提高其性能。我选择的M是7027•611207。这两个素因p和q都具有模余数3(mod 4),并且gcd(φ(p-1),φ(q-1))= 2尽可能小。
尽管这些是Wiki页面上列出的唯一条件,但这似乎还不够。我尝试的所有模数几乎都在每次测试中均失败。但是只有少数几个可以通过一些测试,无论出于何种原因,我选择的测试似乎都非常出色。
最后一点,测试5本身似乎可以很好地表明PRNG的良好程度。如果它几乎没有通过测试5,它将使其余的测试失败。
奖金:Perl 62/14≈4.43
$t=$^T;sub r{$t|=(($s=$s/2|$t%2<<31)^($t/=2))<<31for 1..37;$t}
仅出于怪味,这是原始Tetris for NES中使用的PRNG的32位版本。令人惊讶的是,它通过了15个测试中的14个!
1. passed - Birthday Spacings
2. passed - Overlapping Permutations
3. passed - Ranks of 31x31 and 32x32 Matrices
4. passed - Ranks for 6x8 Matrices
5. passed - Monkey Tests on 20-bit Words
6. passed - Monkey Tests OPSO, OQSO, DNA
7. FAILED - Count the 1s in a Stream of Bytes
8. passed - Count the 1s for Specific Bytes
9. passed - Parking Lot Test
10. passed - Minimum Distance Test
11. passed - Random Spheres Test
12. passed - The Squeeze Test
13. passed - Overlapping Sums Test
14. passed - Runs Test
15. passed - The Craps Test
示例日志文件可以在此处。
诚然,这1..37
不是一个精确的抄写。在原始版本中,熵例程每秒更新60次,然后以随机间隔查询,这在很大程度上取决于用户输入。对于需要拆解ROM的任何人,熵例程均始于0xAB47
。
Python样式的伪代码:
carry = entropy_1 & 1
entropy_1 >>= 1
entropy_2 = (entropy_2 >> 1) | (carry << 31)
carry = (entropy_1 & 1) ^ (entropy_2 & 1)
entropy_1 |= carry << 31