问题描述
PHP 的 rand()
函数不能提供好的随机数.所以我开始使用 mt_rand()
据说可以提供更好的结果.但这些结果有多好?有什么方法可以再次改进它们吗?
PHP's rand()
function doesn't give good random numbers. So I started to use mt_rand()
which is said to give better results. But how good are these results? Are there any methods to improve them again?
我的想法:
function rand_best($min, $max) {
$generated = array();
for ($i = 0; $i < 100; $i++) {
$generated[] = mt_rand($min, $max);
}
shuffle($generated);
$position = mt_rand(0, 99);
return $generated[$position];
}
这应该会给你完美"的随机数,不是吗?
This should give you "perfect" random numbers, shouldn't it?
推荐答案
伪随机数生成器(PRNG) 是非常复杂的野兽.
Pseudorandom number generators (PRNG) are very complex beast.
没有真正完美"的随机数生成器——事实上,最好的数学函数是伪随机的——对于大多数意图和目的来说,它们似乎足够随机.
There are no real "perfect" random number generators -- in fact the best that can be done from mathematical functions are pseudorandom -- they seem random enough for most intents and purposes.
事实上,从 PRNG 返回的数字中执行任何其他操作并不会真正增加其随机性,事实上,该数字可以变得不那么随机.
In fact, performing any additional actions from a number returned by a PRNG doesn't really increase its randomness, and in fact, the number can become less random.
所以,我最好的建议是,不要乱用从 PRNG 返回的值.使用足以满足预期用途的 PRNG,如果不是,则在必要时找到可以产生更好结果的 PRNG.
So, my best advice is, don't mess around with values returned from a PRNG. Use a PRNG that is good enough for the intended use, and if it isn't, then find a PRNG that can produce better results, if necessary.
坦率地说,mt_rand
函数使用 Mersenne twiner,这是一个非常好的 PRNG是的,所以它对于大多数休闲使用来说可能已经足够了.
And frankly, it appears that the mt_rand
function uses the Mersenne twister, which is a pretty good PRNG as it is, so it's probably going to be good enough for most casual use.
但是,Mersenne Twister 并非设计用于任何安全环境.请参阅此答案,了解在需要随机性以确保安全性时使用的解决方案.
However, Mersenne Twister is not designed to be used in any security contexts. See this answer for a solution to use when you need randomness to ensure security.
编辑
评论中有一个问题,为什么对随机数执行操作可以使其不那么随机.例如,一些 PRNG 可以在位的不同部分返回更一致、更少随机数——高端可能比低端更随机.
There was a question in the comments why performing operations on a random number can make it less random. For example, some PRNGs can return more consistent, less random numbers in different parts of the bits -- the high-end can be more random than the low-end.
因此,在丢弃高端并返回低端的操作中,该值可能变得比从 PRNG 返回的原始值更不随机.
Therefore, in operations where the high-end is discarded, and the low end is returned, the value can become less random than the original value returned from the PRNG.
我目前找不到很好的解释,但我基于 Random.nextInt(int)
方法,旨在在指定范围内创建一个相当随机的值.该方法考虑了值各部分的随机性差异,因此与 rand() % range
等更简单的实现相比,它可以返回更好的随机数.
I can't find a good explanation at the moment, but I based that from the Java documentation for the Random.nextInt(int)
method, which is designed to create a fairly random value in a specified range. That method takes into account the difference in randomness of the parts of the value, so it can return a better random number compared to more naive implementations such as rand() % range
.
这篇关于在 php 中生成加密安全的随机数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!