首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用PHP5.6在范围内生成安全的随机整数

用PHP5.6在范围内生成安全的随机整数
EN

Stack Overflow用户
提问于 2015-09-23 06:55:44
回答 3查看 3.7K关注 0票数 3

我想在PHP5.6中的$min$max之间生成一个安全的随机整数。PHP中的rand()mt_rand()都被认为不是密码安全的。

来自文档

警诫 此函数不生成加密安全值,不应用于加密目的。如果需要加密安全的值,可以考虑使用random_int()、random_bytes()或openssl_random_pseudo_bytes()。

PHP7添加了random_int() (文档),非常适合我的用例:

random_int -生成加密安全伪随机整数

但是,如何在PHP5.6中实现这个功能呢?

我天真的尝试是:

代码语言:javascript
复制
<?php
function secure_rand($min, $max)
{
    return (unpack("N", openssl_random_pseudo_bytes(4)) % ($max - $min)) + $min;
}

但是,当我调用secure_rand(1, 100)时,我似乎总是得到"2“。我也读过用这种方式使用模数运算可以产生偏置。如何在PHP5.6中模仿random_int()

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-09-23 17:44:22

我可以向您介绍一下康帕特吗?在PHP5项目中,哪个多边形填充了random_bytes()random_int()?(Sidenote:在其他项目中,它是由Wordpress在4.4中获得的。)

代码语言:javascript
复制
function secure_rand($min, $max)
{
    return (unpack("N", openssl_random_pseudo_bytes(4)) % ($max - $min)) + $min;
}

即使这是您想要做的事情,这也是一个偏置随机数发生器,而($max - $min)并不是2的偶数。

票数 7
EN

Stack Overflow用户

发布于 2015-09-23 07:44:39

找到了一个很好的解决方案。在本例中,使用了mcrypt扩展,但如果需要更多信息,请参见openssl_random_pseudo_bytes() ( 这里 ),它也适用于这里

代码语言:javascript
复制
function secure_rand( $min, $max ) {
    $diff = $max - $min;
    if ($diff < 0 || $diff > 0x7FFFFFFF) {
        throw new RuntimeException("Bad range");
    }
    $bytes = mcrypt_create_iv( 4, MCRYPT_DEV_URANDOM );

    // if mcrypt is not enabled on your server, you can use this
    //$bytes = openssl_random_pseudo_bytes( 4 );

    // if mbstring is not enabled, you can also use iconv_strlen
    if ($bytes === false || mb_strlen($bytes, '8bit') != 4) {
        throw new RuntimeException("Unable to get 4 bytes");
    }

    $ary = unpack("Nint", $bytes);
    $val = $ary['int'] & 0x7FFFFFFF;   // 32-bit safe
    $fp = $val / 2147483647.0; // convert to [0,1]
    // if you really need a type of int take this
    // return (int) round($fp * $diff) + $min;
    // otherwise it will return a float without decimal numbers
    return round($fp * $diff) + $min;
}

var_dump( secure_rand( 1, 1000 ) );
var_dump( secure_rand( 1, 20 ) );
var_dump( secure_rand( 1, 10 ) );
var_dump( secure_rand( 1, 5000 ) );
var_dump( secure_rand( 1, 1111111 ) );

更新:源中的注释,将强制转换为浮动/int,使用mb_strlen()而不是strlen()

票数 2
EN

Stack Overflow用户

发布于 2015-09-23 07:08:32

您可以使用openssl_random_pseudo_bytes,,因为它可以从PHP5.3中获得。

生成一个伪随机字节字符串,其字节数由长度参数确定. 它还指示是否使用加密强算法来生成伪随机字节,并通过可选的crypto_strong参数进行此操作。这是很少见的错误,但有些系统可能是坏的或旧的。

PHP文档阅读更多内容

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32732940

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档