php mt_rand() 和 rand() 的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28760650/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between mt_rand() and rand()
提问by Thomas Rbt
What is the difference between using mt_rand($min, $max)
and rand($min, $max)
about the speed?
usingmt_rand($min, $max)
和rand($min, $max)
about speed 有什么区别?
回答by Elias Van Ootegem
Update
更新
Since PHP 7.1 mt_rand
has superseded rand
completely, and rand
was made an alias for mt_rand
. The answer below focuses on the differences between the two functions for older versions, and the reasons for introducing mt_rand
.
由于 PHP 7.1mt_rand
已rand
完全取代,并rand
成为mt_rand
. 下面的回答主要针对旧版本的两个函数的区别,以及引入mt_rand
.
Speed was not why mt_rand
was introduced!
速度不是为什么mt_rand
被引入!
The rand
function existed way before mt_rand
, but it was deeply flawed. A PRNG must get some entropy, a number from which it generates a sequence of random numbers. If you print out a list of ten numbers that were generated by rand()
like so:
该rand
功能以前存在mt_rand
,但存在严重缺陷。PRNG 必须获得一些熵,即生成随机数序列的数字。如果您打印出由rand()
如下生成的十个数字的列表:
for ($i=0;$i<10;++$i)
echo rand(), PHP_EOL;
The output can be used to work out what the rand
seed was, and with it, you can predict the next random numbers. There are tools out there that do this, so google a bit and test it.
输出可用于计算出rand
种子是什么,并用它来预测下一个随机数。有一些工具可以做到这一点,所以谷歌一下并测试它。
There's also an issue with rand
relativily quickly showing patterns in its random numbers as demonstrated here. A problem mt_rand
seems to solve a lot better, too.
还有有问题rand
relativily迅速显示在它的随机数的图案作为这里展示。一个问题mt_rand
似乎也能更好地解决。
mt_rand
uses a better randomization algorithm (Mersenne Twist), which requires more random numbers to be known before the seed can be determined andis faster. This does not mean that mt_rand
is, by definition, faster than rand
is, this only means that the way the numbers are generated is faster, and appears to have no real impact on the function's performance, as other answers here have demonstrated.
Either way, have a look at the mt_srand
and the srand
docs. I'm sure they'll contain some more info
mt_rand
使用更好的随机化算法(Mersenne Twist),它需要在确定种子之前知道更多的随机数并且速度更快。这并不意味着mt_rand
,根据定义,比rand
is更快,这仅意味着生成数字的方式更快,并且似乎对函数的性能没有真正的影响,正如这里的其他答案所证明的那样。
无论哪种方式,看看在mt_srand
和该srand
文档。我相信他们会包含更多信息
If mt_rand
's algorithm translates in an increase in performance, then that's great for you, but it's a happy coincidence. TL;TR:
如果mt_rand
的算法转化为性能的提高,那么这对您来说很好,但这是一个快乐的巧合。TL;TR:
mt_rand
was introduced to fix the problems that exist in rand
!
mt_rand
被引入来解决存在的问题rand
!
回答by OscarGarcia
Update (PHP 7.1):
更新(PHP 7.1):
rand()
andsrand()
have now been made aliases tomt_rand()
andmt_srand()
, respectively.This means that the output for the following functions have changes:rand()
,shuffle()
,str_shuffle()
, andarray_rand()
.
rand()
和srand()
现在分别成为mt_rand()
和 的别名mt_srand()
。这意味着,输出用于以下功能有变化:rand()
,shuffle()
,str_shuffle()
,和array_rand()
。
That means that since version 7.1 there is no practical difference between both of them because rand
calls mt_rand
internally.
这意味着从 7.1 版开始,它们之间没有实际区别,因为在内部rand
调用mt_rand
.
Before PHP 7.1:
PHP 7.1 之前:
Using rand()
is not a bad practice if it not used for security purposes, I'm usually using rand()
(habit?).
rand()
如果不用于安全目的,使用并不是一个坏习惯,我通常使用rand()
(习惯?)。
If you need an enormous amount of random numbers you will need mt_rand
instead rand
. mt_rand
has a period of 219937? 1, far better than rand
(232). Take a look to this articleabout graphical pattern generation using rand
and mt_rand
.
如果你需要的随机数的大量,您将需要mt_rand
代替rand
。mt_rand
有一个时期 2 19937? 1,远好于rand
(2 32)。看看这篇关于使用rand
和生成图形模式的文章mt_rand
。
Periodicityand entropyare the only reasons for using mt_rand()
instead rand()
and not security or speed improvements.
周期性和熵是使用的唯一原因,mt_rand()
而rand()
不是安全性或速度改进。
Mathematically mt_rand
have more entropyand a greater periodicitythan rand
(219937?1 vs. 232).
在数学上比(2 19937?1 vs. 2 32)mt_rand
具有更多的熵和更大的周期性。rand
If you need a few random numbers and security is not a problem, rand
will do the job (get a random number to decide firing a cleanup process).
如果您需要一些随机数并且安全性不是问题,则rand
可以完成这项工作(获得一个随机数来决定启动清理过程)。
Testing speed improvements
测试速度提升
In practice there is not much difference in speed between the two functions (maybe because PHP?C wrapper overhead?).
实际上,这两个函数之间的速度没有太大差异(可能是因为 PHP?C 包装器开销?)。
PHP test code:
PHP测试代码:
<?php
for ($c = 0; $c < 3; $c++) {
$start = microtime(true);
$sum = 0.0;
for ($i = 0; $i < 100000000; $i++) {
$sum += rand();
}
printf('[rand %d] Time: %.3f s%s', $c, microtime(true) - $start, PHP_EOL);
}
for ($c = 0; $c < 3; $c++) {
$start = microtime(true);
$sum = 0.0;
for ($i = 0; $i < 100000000; $i++) {
$sum += mt_rand();
}
printf('[mt_rand %d] Time: %.3f s%s', $c, microtime(true) - $start, PHP_EOL);
}
Tests in PHP 7.0.19:
PHP 7.0.19 中的测试:
$ php timing.php
[rand 0] Time: 4.658 s
[rand 1] Time: 4.664 s
[rand 2] Time: 4.654 s
[mt_rand 0] Time: 4.267 s
[mt_rand 1] Time: 4.255 s
[mt_rand 2] Time: 4.261 s
Tests in PHP 5.4.45 (slower machine):
PHP 5.4.45(较慢的机器)中的测试:
$ php timing.php
[rand 0] Time: 10.862 s
[rand 1] Time: 10.889 s
[rand 2] Time: 10.615 s
[mt_rand 0] Time: 10.948 s
[mt_rand 1] Time: 9.883 s
[mt_rand 2] Time: 10.190 s
Only 6-9% and not 400% as claimed.
只有 6-9% 而不是声称的 400%。
Using for security purposes
用于安全目的
But if your application needs a lot of entropy because security issues, you'll need a more secure way and openssl_random_pseudo_bytes()
possibly is the best solution, does its work (far better but slower? we need security over speed?) relying on openssl related issues.
但是,如果您的应用程序因为安全问题而需要大量熵,那么您将需要一种更安全的方法,并且openssl_random_pseudo_bytes()
可能是最好的解决方案,它是否工作(更好但更慢?我们需要安全性超过速度?)依赖于 openssl 相关问题。
Neither rand()
nor mt_rand()
are safe enough:
既不安全rand()
也不mt_rand()
安全:
CautionThis function does not generate cryptographically secure values, and should not be used for cryptographic purposes. If you need a cryptographically secure value, consider using
random_int()
,random_bytes()
, oropenssl_random_pseudo_bytes()
instead.
注意此函数不会生成加密安全值,不应用于加密目的。如果你需要一个加密的安全值,可以考虑使用
random_int()
,random_bytes()
或openssl_random_pseudo_bytes()
代替。
There is PHP extensions like random_compat
, but I didn't recommend using them if it not necessary.
有像 的 PHP 扩展random_compat
,但如果没有必要,我不建议使用它们。
回答by Bell
As of PHP 7.1 there is no difference at all. rand() is now an alias for mt_rand().
从 PHP 7.1 开始,完全没有区别。rand() 现在是 mt_rand() 的别名。
See http://php.net/manual/en/migration71.incompatible.php#migration71.incompatible.rand-srand-aliases
请参阅http://php.net/manual/en/migration71.incompatible.php#migration71.incompatible.rand-srand-aliases
And more details: https://wiki.php.net/rfc/rng_fixes
以及更多详细信息:https: //wiki.php.net/rfc/rng_fixes
回答by Forien
回答by PHP Team
Following is the difference in speed for both of them :-mt_rand($min, $max)
is fourtimes faster as compared to rand($min, $max)
The reason is that,rand($min, $max)
uses libc random number generatorwhile mt_rand($min, $max)
uses Mersenne Twisterwhich is four times faster.
Hope it will solve your doubt.
Thanks.
以下是他们两人的速度差异: -mt_rand($min, $max)
是4比快倍rand($min, $max)
的原因在于,rand($min, $max)
使用 libc的随机数生成器,同时mt_rand($min, $max)
使用梅森倍捻机是快四倍。
希望它能解决你的疑惑。
谢谢。
回答by georg
They appear to be equal in speed:
它们的速度似乎相等:
function timeit($times, $func) {
$t = microtime(1);
while($times--) $func();
return microtime(1) - $t;
}
echo PHP_OS, " ", phpversion(), "\n";
echo timeit(100000, function() { rand(0,1000); }), "\n";
echo timeit(100000, function() { mt_rand(0,1000); }), "\n";
Results for OSX Mavericks and VirtualBox'ed Ubuntu 11:
OSX Mavericks 和 VirtualBox'ed Ubuntu 11 的结果:
Darwin 5.5.19
0.038038969039917
0.033117055892944
Linux 5.3.6-13ubuntu3.10
0.031459093093872
0.031935214996338
If these measures are correct, the manual comment mentioned elsewhere should be considered wrong/obsolete.
如果这些措施是正确的,那么其他地方提到的手动注释应该被认为是错误的/过时的。