我正在编写一个孩子姐妹加密函数,我需要一个PRNG,它可以在OS上产生一致的结果(所以没有浮点数学,利用硬件或系统级软件).如果PRNG的持续时间超过2 30,这将是一件好事,但并非必要.
我目前正在使用32位Xorshift:
#!/usr/bin/perl use strict; use warnings; { use integer; #use integer math my $x = 123456789; my $y = 362436069; my $w = 88675123; my $z = 521288629; sub set_random_seed { $w = shift; } sub random { my $t = $x ^ ($x << 11); $x = $y; $y = $z; $z = $w; my $rand = $w = ($w ^ ($w >> 19)) ^ ($t ^ ($t >> 8)); return $rand % 256; #scale it back to a byte at a time } } set_random_seed(5); print map { random(), "\n" } 1 .. 10;
但我很担心,因为我真的不明白它是如何运作的.例如,原始源没有设置种子的能力,所以我添加了一个,但我不知道我是否为种子选择了正确的变量.
所以,所有这些归结为
您知道CPAN上的模块是否符合我的需求?
如果没有,您知道哪种算法符合我的需求吗?
unwind.. 7
Math :: Random :: Auto是一个CPAN模块,用于实现着名的Mersenne twister PRNG.
Math :: Random :: Auto是一个CPAN模块,用于实现着名的Mersenne twister PRNG.
尝试使用LFSR - 线性反馈移位寄存器..Ť 他首先联系上的外部链接有你需要出示任何数量的随机性位的一切.关于这一点的好处是它易于实现,并且可以使用所有整数数学来完成.
我在8051项目上成功使用了它.使用perl它将是一个快照.
更新:
这是一个8位LFSR的快速perl实现:
use strict; use warnings; use List::Util qw(reduce); use vars qw($a $b); print 'Taps: ', set_taps( 8, 7, 2, 1 ), "\n"; print 'Seed: ', seed_lfsr( 1 ), "\n"; print read_lfsr(), "\n" for 1..10; BEGIN { my $tap_mask; my $lfsr = 0; sub read_lfsr { $lfsr = ($lfsr >> 1) ^ (-($lfsr & 1) & $tap_mask ); return $lfsr; } sub seed_lfsr { $lfsr = shift || 0; $lfsr &= 0xFF; } sub set_taps { my @taps = @_; $tap_mask = reduce { $a + 2**$b } 0, @taps; $tap_mask >>= 1; $tap_mask &= 0xFF; return $tap_mask; } }
这段代码只是一个原型.如果我想在生产中使用它,我可能会将它包装在一个对象中,并使寄存器大小可配置.然后我们将摆脱那些讨厌的共享变量.