作为http://VM-MASTEr:8088/cluster random_int()
函数生成加密安全的伪随机整数。
但是,有人可以解释rand()
&之间的差异吗? random_int()
?只需要一个随机整数时,我可以使用random_int()
代替rand()
吗?哪一个更快?
答案 0 :(得分:13)
重新审视这个问题并看到答案已经给出了答案,我发现将评论提交给答案是公平的,因为他们之前已经提交了答案。
PHP 7' random_int()
函数的手册说明:
"返回加密安全随机整数,范围为min到max(包括)。"
和rand()
*此功能不会生成加密安全值" *
OP的评论:
" @ Fred-ii-谢谢你。但是"加密安全伪随机"意思? - NDFA"
根据我的发现,可以在以下链接中找到:
哪个州:
加密安全伪随机数生成器(CSPRNG)或加密伪随机数生成器(CPRNG)[1]是伪随机数生成器(PRNG),其属性使其适用于加密的
关于性能,您需要自己运行基准测试。
答案 1 :(得分:8)
从PHP 7.1开始,rand()
基本上是mt_rand()
的别名。较新的random_int()
是三者中最慢但唯一安全的方法。
<?php
$start = microtime(true);
$sum = 0.0;
for ($i = 0; $i < 10000000; $i++) {
$sum += rand(0, 32767);
}
printf('[rand] Time: %.3f s%s', microtime(true) - $start, PHP_EOL);
$start = microtime(true);
$sum = 0.0;
for ($i = 0; $i < 10000000; $i++) {
$sum += mt_rand(0, 32767);
}
printf('[mt_rand] Time: %.3f s%s', microtime(true) - $start, PHP_EOL);
$start = microtime(true);
$sum = 0.0;
for ($i = 0; $i < 10000000; $i++) {
$sum += random_int(0, 32767);
}
printf('[random_int] Time: %.3f s%s', microtime(true) - $start, PHP_EOL);
结果:
[rand] Time: 10.973 s
[mt_rand] Time: 9.628 s
[random_int] Time: 23.069 s
答案 2 :(得分:3)
作为大多数数字生成器,使用rand()是不安全的,因为它不会生成加密安全值,并且rand()的输出是可预测的。
PHP 7.0引入了random_bytes和random_int作为核心函数,它们没有大多数随机数生成器所具有的问题。
答案 3 :(得分:1)
rand()
现在是mt_rand()
的别名。观察source code of mt_rand(),可以看出随机数根本不是随机的。这是一个简单的数学计算,没有比
return $min + suffle_bits($internal_counter++) % ($max - $min);
其中suffle_bits()
是一些可预测的二进制算法,使它看起来像$internal_counter
并不只是在增加自身。
这就是为什么说rand()
返回伪随机数字的原因。返回的数字似乎是随机绘制的,但是知道$internal_counter
的值可以让您预测接下来的情况。
random_int()
不会受到此可预测性问题的困扰,只要计算机的熵生成器已正确启动即可。
即使攻击者收集了大量值,也无法猜测下一个值。
如果攻击者可以从代码输出中猜测$internal_counter
的值,并利用该知识来干扰代码的预期用途,请使用random_int()
。
如果使用随机数显示(例如随机问候),那么rand()
是绝对安全的。
现在,如果必须生成一长串GUID或条形码,并且最终用户必须不能从子集中猜出另一个有效值,那么random_int()
不仅对安全性有好处,还因为它不会不再重复。根据平台的不同,rand()
可能会以32768的输出速度迅速重复自身。
毫无疑问,rand()
更简单,因此也更快。
这是一个粗略的单行易复制/粘贴命令,用于计算在10秒内可以从rand()
提取多少个数字:
php -r '$s=microtime(true);$c=0;while(microtime(true)-$s<10){rand(0,9);$c++;};echo "$c\n";'
与random_int()
相同:
php -r '$s=microtime(true);$c=0;while(microtime(true)-$s<10){random_int(0,9);$c++;};echo "$c\n";'
php 7.3的计数器为:
rand(): 36665142
random_int(): 10511327
rand()
的速度不到4倍。除非速度不成问题,否则random_int()
是必经之路,但对于最基本的非关键任务而言。
答案 4 :(得分:0)
我个人使用random_int并没有遇到任何问题,但是应该将其与try / catch一起使用,因为如果无法收集足够的熵,它将引发异常。
答案 5 :(得分:0)
补充 Frédéric 响应,在 PHP 8.0.3 中,random_int()
似乎比以前快了很多,使用他自己的代码示例。
与:
<?php
echo "this will take 20 seconds\n\n";
echo "generating random with 'rand' method\n";
$s1=microtime(true);$c1=0;while(microtime(true)-$s1<10){rand(0,65535);$c1++;};
$fc1 = number_format($c1 , 0, ',', '.');
echo "generated: $fc1\n\n";
echo "generating random with 'random_int' method\n";
$s2=microtime(true);$c2=0;while(microtime(true)-$s2<10 {random_int(0,65535);$c2++;};
$fc2 = number_format($c2 , 0, ',', '.');
echo "generated: $fc2\n\n";
?>
我得到了输出:
this will take 20 seconds
generating random with 'rand' method
generated: 48.423.988
generating random with 'random_int' method
generated: 30.843.067
在他的测试中,random_int()
比 rand()
慢三倍多。
在这些中,random_int()
仅比 rand()
慢 40%。
PS:我将最大随机值从 9 增加到 65535 供个人使用,似乎实际上提高了两种情况的速度。