两个问题:
我会为每个种子获得不同的数字序列吗?
是否有一些"死"的种子?(产生零或快速重复的那些.)
顺便说一句,我应该使用哪些其他PRNG?
解决方案:因为,我将使用PRNG来制作游戏,我不需要它在加密方面是安全的.我要和Mersenne Twister一起去,因为它的速度和时间很长.
在某种程度上,随机数发生器是课程的马匹.Random类使用合理选择的参数实现LCG.但它仍然具有以下特点:
相当短的时期(2 ^ 48)
位不是同等随机的(参见我关于位位置随机性的文章)
只会产生一小部分价值组合(着名的" 落在飞机上 ")
如果这些事情对您无关紧要,则Random具有作为JDK的一部分提供的兑换功能.这对于休闲游戏(但不包括涉及金钱的游戏)来说已经足够了.这样没有弱种子.
另一个替代方案是XORShift生成器,可以用Java实现如下:
public long randomLong() { x ^= (x << 21); x ^= (x >>> 35); x ^= (x << 4); return x; }
对于一些非常便宜的操作,它的周期为2 ^ 64-1(不允许为零),并且当您重复生成值时,它很简单,可以内联.各种移位值都是可能的:有关详细信息,请参阅George Marsaglia关于XORShift发生器的论文.您可以将生成的数字中的位视为同等随机.一个主要的弱点是偶尔它会进入一个"车辙",其中数字中没有设置很多位,然后需要几代才能摆脱这个车辙.
其他可能性是:
组合不同的发生器(例如,将XORShift发生器的输出馈入LCG,然后将结果添加到具有不同参数的XORShift发生器的输出):这通常允许不同方法的弱点被"平滑",并且可以如果仔细选择组合发电机的周期,则给出更长的时间
添加"滞后"(以给出更长的时间段):基本上,在生成器通常将变换生成的最后一个数字的情况下,存储"历史缓冲区"并转换,例如,(n-1023).
我会说避免使用愚蠢数量的内存的生成器给你一个比你真正需要的更长的时间(有些时间段大于宇宙中的原子数 - 你通常不需要那个).请注意,"长周期"并不一定意味着"高质量发电机"(尽管2 ^ 48仍然有点低!).
正如zvrba所说,JavaDoc解释了正常的实现.关于伪随机数生成器的维基百科页面有相当多的信息,并提到了Mersenne twister,它不被认为是加密安全的,但速度非常快,并且在Java中有各种实现.(最后一个链接有两个实现 - 我相信还有其他实现.)
如果您需要加密安全生成,请阅读维基百科页面 - 有各种选项可供选择.
随着RNG的发展,Sun的实施绝对不是最先进的,但对于大多数用途来说已经足够了.如果您需要随机数用于加密目的,那么有java.security.SecureRandom,如果您只想要比java.util.random更快更好的东西,那么很容易在网上找到Mersenne Twister的Java实现.