mt_rand的缺点是什么?

时间:2021-11-10 18:22:53

What's the definition of bias in:

偏见的定义是什么?

The distribution of mt_rand() return values is biased towards even numbers on 64-bit builds of PHP when max is beyond 2^32.

mt_rand()返回值的分布偏向偶数在64位构建PHP当马克斯超出2 ^ 32。

If it's the kind of bias stated in alternate tie-breaking rules for rounding, I don't think it really matters (since the bias is not really visible).

如果这是另一种关于“四舍两入”的规则,我不认为这真的很重要(因为偏见是不可见的)。

Besides mt_rand() is claimed to be four times faster than rand(), just by adding three chars in front!

此外,声称mt_rand()比rand()快四倍,只需在前面添加三个字符!

Assuming mt_rand is available, what's the disadvantage of using it?

假设mt_rand可用,那么使用它的缺点是什么?

2 个解决方案

#1


57  

mt_rand uses the Mersenne Twister algorithm, which is far better than the LCG typically used by rand. For example, the period of an LCG is a measly 232, whereas the period of mt_rand is 219937 − 1. Also, all the values generated by an LCG will lie on lines or planes when plotted into a multidimensional space. Also, it is not only practically feasible, but relatively easy to determine the parameters of an LCG. The only advantage LCGs have is being potentially slightly faster, but on a scale that is completely irrelevant when coding in php.

mt_rand使用了Mersenne Twister算法,这比rand所使用的LCG好得多。例如,期间一个LCG区区232,而mt_rand 219937−1期。此外,LCG生成的所有值在绘制成多维空间时将位于线或平面上。同时,它不仅在实际应用中是可行的,而且相对容易确定LCG的参数。LCGs的唯一优势是可能稍微快一点,但是在php代码中完全不相关的规模上。

However, mt_rand is not suitable for cryptographic purposes (generation of tokens, passwords or cryptographic keys) either.

但是,mt_rand也不适用于加密目的(生成令牌、密码或密码键)。

If you need cryptographic randomness, use random_int in php 7. On older php versions, read from /dev/urandom or /dev/random on a POSIX-conforming operating system.

如果需要密码随机性,请在php 7中使用random_int。在较老的php版本中,在符合posix的操作系统上读取/dev/urandom或/dev/random。

#2


8  

The distribution quirk that you quoted is only relevant when the random number range you're generating is larger than 2^32. That is 4294967296.

你报的分布特性,只是相关当你生成的随机数范围大于2 ^ 32。这是4294967296。

If you're working with numbers that big, and you need them to be randomised, then perhaps this is a reason to reconsider using mt_rand(). However if your working with numbers smaller than this, then it is irrelevant.

如果您正在处理这么大的数字,并且需要它们是随机的,那么这可能是使用mt_rand()重新考虑的一个原因。然而,如果你的数字比这个小,那就无关紧要了。

The reason it happens is due to the precision of the random number generator not being good enough in those high ranges.

发生这种情况的原因是随机数生成器的精度在这些高范围内不够好。

I've never worked with random numbers that large, so I've never needed to worry about it.

我从来没有使用过这么大的随机数,所以我从来不用担心它。

The difference between rand() and mt_rand() is a lot more than "just three extra characters". They are entirely different function calls, and work in completly different ways. Just the same as you don't expect print() and print_r() to be similar.

rand()和mt_rand()之间的区别远不止“三个额外的字符”。它们是完全不同的函数调用,以完全不同的方式工作。就像您不希望print()和print_r()类似一样。

mt_rand() gets it's name from the "Mersene Twister" algorithm it uses to generate the random numbers. This algorithm is known to be a quick, efficient and high quality random number generator, which is why it is available in PHP.

mt_rand()从它用来生成随机数的“Mersene Twister”算法中得到它的名字。该算法是一种快速、高效、高质量的随机数生成器,这就是为什么它在PHP中可用的原因。

The older rand() function makes use of the operating system's random number generator by making a system call. This means that it uses whatever random number generator happens to be the default on the operating system you're using. In general, the default random number generator uses a much slower and older algorithm, hence the claim that my_rand() is quicker, but it will vary from system to system.

旧的rand()函数通过系统调用来使用操作系统的随机数生成器。这意味着它使用的随机数生成器是您正在使用的操作系统的默认值。一般来说,默认的随机数生成器使用的是一种速度更慢、更老的算法,因此my_rand()更快,但是系统之间会有所不同。

Therefore, for virtually all uses, mt_rand() is a better function to use than rand().

因此,对于几乎所有的使用,mt_rand()是比rand()更好的函数。

You say "assuming mt_rand() is available", but it always will be since it was introduced way back in PHP4.

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

#1


57  

mt_rand uses the Mersenne Twister algorithm, which is far better than the LCG typically used by rand. For example, the period of an LCG is a measly 232, whereas the period of mt_rand is 219937 − 1. Also, all the values generated by an LCG will lie on lines or planes when plotted into a multidimensional space. Also, it is not only practically feasible, but relatively easy to determine the parameters of an LCG. The only advantage LCGs have is being potentially slightly faster, but on a scale that is completely irrelevant when coding in php.

mt_rand使用了Mersenne Twister算法,这比rand所使用的LCG好得多。例如,期间一个LCG区区232,而mt_rand 219937−1期。此外,LCG生成的所有值在绘制成多维空间时将位于线或平面上。同时,它不仅在实际应用中是可行的,而且相对容易确定LCG的参数。LCGs的唯一优势是可能稍微快一点,但是在php代码中完全不相关的规模上。

However, mt_rand is not suitable for cryptographic purposes (generation of tokens, passwords or cryptographic keys) either.

但是,mt_rand也不适用于加密目的(生成令牌、密码或密码键)。

If you need cryptographic randomness, use random_int in php 7. On older php versions, read from /dev/urandom or /dev/random on a POSIX-conforming operating system.

如果需要密码随机性,请在php 7中使用random_int。在较老的php版本中,在符合posix的操作系统上读取/dev/urandom或/dev/random。

#2


8  

The distribution quirk that you quoted is only relevant when the random number range you're generating is larger than 2^32. That is 4294967296.

你报的分布特性,只是相关当你生成的随机数范围大于2 ^ 32。这是4294967296。

If you're working with numbers that big, and you need them to be randomised, then perhaps this is a reason to reconsider using mt_rand(). However if your working with numbers smaller than this, then it is irrelevant.

如果您正在处理这么大的数字,并且需要它们是随机的,那么这可能是使用mt_rand()重新考虑的一个原因。然而,如果你的数字比这个小,那就无关紧要了。

The reason it happens is due to the precision of the random number generator not being good enough in those high ranges.

发生这种情况的原因是随机数生成器的精度在这些高范围内不够好。

I've never worked with random numbers that large, so I've never needed to worry about it.

我从来没有使用过这么大的随机数,所以我从来不用担心它。

The difference between rand() and mt_rand() is a lot more than "just three extra characters". They are entirely different function calls, and work in completly different ways. Just the same as you don't expect print() and print_r() to be similar.

rand()和mt_rand()之间的区别远不止“三个额外的字符”。它们是完全不同的函数调用,以完全不同的方式工作。就像您不希望print()和print_r()类似一样。

mt_rand() gets it's name from the "Mersene Twister" algorithm it uses to generate the random numbers. This algorithm is known to be a quick, efficient and high quality random number generator, which is why it is available in PHP.

mt_rand()从它用来生成随机数的“Mersene Twister”算法中得到它的名字。该算法是一种快速、高效、高质量的随机数生成器,这就是为什么它在PHP中可用的原因。

The older rand() function makes use of the operating system's random number generator by making a system call. This means that it uses whatever random number generator happens to be the default on the operating system you're using. In general, the default random number generator uses a much slower and older algorithm, hence the claim that my_rand() is quicker, but it will vary from system to system.

旧的rand()函数通过系统调用来使用操作系统的随机数生成器。这意味着它使用的随机数生成器是您正在使用的操作系统的默认值。一般来说,默认的随机数生成器使用的是一种速度更慢、更老的算法,因此my_rand()更快,但是系统之间会有所不同。

Therefore, for virtually all uses, mt_rand() is a better function to use than rand().

因此,对于几乎所有的使用,mt_rand()是比rand()更好的函数。

You say "assuming mt_rand() is available", but it always will be since it was introduced way back in PHP4.

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