php 随机兰德()与随机数_int()

vs3odd8k  于 2023-03-07  发布在  PHP
关注(0)|答案(6)|浏览(204)

As php.net indicates:random_int()函数 * 生成加密安全的伪随机整数 *。
但是,有人能解释一下rand()random_int()之间的区别吗?当只需要一个随机整数时,我能用random_int()代替rand()吗?哪一个更快?

bxpogfeg

bxpogfeg1#

重新审视这个问题,看到已经给出了答案,我发现这是唯一公平的,我提交我的意见的答案,看到他们提交之前。
PHP 7的random_int()函数手册指出:

对于rand()

OP评论:

  • "@Fred-ii-谢谢。但是“加密安全伪随机”是什么意思?- NDFA”*

根据我的调查结果,可以在以下链接中找到:

其中指出:

在性能方面,您需要自己运行基准测试。

u5i3ibmn

u5i3ibmn2#

从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);

PHP 7.4上的结果:

[rand] Time: 0.320 s      
[mt_rand] Time: 0.326 s   
[random_int] Time: 9.255 s
js81xvg6

js81xvg63#

兰德()

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()是要走的路,但对于最基本的非关键任务来说。

14ifxucb

14ifxucb4#

与大多数数字生成器一样,使用兰德()是不安全的,因为它不会生成加密安全的值,而且rand()的输出是可预测的。
PHP 7.0引入了random_bytes和random_int作为核心函数,它们没有大多数随机数生成器所具有的问题。

icomxhvb

icomxhvb5#

作为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,以供个人使用,这似乎实际上增加了两种情况的速度。
dwbf0jvd

dwbf0jvd6#

我个人在使用random_int时没有遇到过任何问题,但它应该与try/catch一起使用,因为如果不可能收集足够的熵,它会抛出异常。

相关问题