mt_rand有什么缺点?

时间:2011-10-18 13:31:24

标签: php random rounding

偏见的定义是什么:

  

当max超过2 ^ 32时,mt_rand()返回值的分布偏向于64位版本的PHP上的偶数。

如果是alternate tie-breaking rules for rounding中所述的那种偏见,我认为这并不重要(因为偏见不是真的可见)。

除了mt_rand() claimedrand()快四倍,只需在前面添加三个字符!

假设mt_rand可用,使用它有什么不利之处?

2 个答案:

答案 0 :(得分:57)

mt_rand使用Mersenne Twister算法,该算法远优于rand通常使用的LCG。例如,LCG的周期是2 32 ,而mt_rand的周期是2 19937 - 1.此外,LCG生成的所有值将{绘制到多维空间时{3}}。而且,它不仅实际可行,而且相对容易确定LCG的参数。 LCG具有的唯一优势可能是稍微快一点,但在PHP编码时完全无关紧要。

但是,mt_rand 不适合加密目的(生成令牌,密码或加密密钥)。

如果您需要加密随机性,请在php 7中使用lie on lines or planes。在较旧的php版本上,请阅读符合POSIX的操作系统上的/dev/urandom/dev/random

答案 1 :(得分:8)

您引用的分布奇怪仅在您生成的随机数范围大于2 ^ 32时才相关。那是4294967296。

如果你正在使用那些大的数字,并且你需要将它们随机化,那么这可能是重新考虑使用mt_rand()的原因。但是,如果您使用的数字小于此值,则无关紧要。

它发生的原因是由于随机数发生器的精度在这些高范围内不够好。

我从未使用过大的随机数,所以我从来不需要担心它。

rand()mt_rand()之间的差异远远大于“仅仅三个额外字符”。它们是完全不同的函数调用,并且以完全不同的方式工作。与您不希望print()print_r()相似的情况一样。

mt_rand()从用于生成随机数的“Mersene Twister”算法中获取它的名称。众所周知,这种算法是一种快速,高效和高质量的随机数生成器,这就是它在PHP中可用的原因。

较旧的rand()函数通过进行系统调用来使用操作系统的随机数生成器。这意味着它使用任何随机数生成器恰好是您正在使用的操作系统上的默认值。一般来说,默认的随机数生成器使用更慢,更老的算法,因此声称my_rand()更快,但它会因系统而异。

因此,对于几乎所有用途,mt_rand()rand()使用的功能更好。

你说“假设mt_rand()可用”,但它总是会在PHP4中引入。