将rand()替换为openssl_random_pseudo_bytes() [英] replace rand() with openssl_random_pseudo_bytes()

查看:254
本文介绍了将rand()替换为openssl_random_pseudo_bytes()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要替换PHP的 rand()函数,它使用一个密码强的随机数生成器。



openssl_random_pseudo_bytes()函数可以访问强随机数生成器,字节字符串。相反,我需要一个介于0和 X之间的整数



我想象的关键是获得输出 openssl_random_pseudo_bytes ()为一个整数,那么你可以做任何你需要的数学。我可以想到几个从字节字符串转换为整数的强力方法,但我希望有一些...优雅。

解决方案

使用提供的建议,我使用OpenSSL为rand()创建了一个替换。我会把它包括在这里为后代。



$ pedantic 选项提供无偏差结果,当结果不会在可能范围内均匀分布时重新开始。

  function crypto_rand($ min,$ max,$ pedantic = True){
$ diff = $ max - $ min;
if($ diff< = 0)return $ min; // not so random ...
$ range = $ diff + 1; //因为$ max是包含的
$ bits = ceil(log(($ range),2));
$ bytes = ceil($ bits / 8.0);
$ bits_max = 1<< $ bit;
//例如如果$ range = 3000(bin:101110111000)
// + -------- + -------- +
// | .... 1011 | 10111000 |
// + -------- + -------- +
// bits = 12,bytes = 2,bits_max = 2 ^ 12 = 4096
$ num = 0;
do {
$ num = hexdec(bin2hex(openssl_random_pseudo_bytes($ bytes)))%$ bits_max;
if($ num> = $ range){
if($ pedantic)continue; //重新开始,而不是接受偏见
// else
$ num = $ num%$ range; // to hell with security
}
break;
} while(True); //因为goto会吸引速食者
return $ num + $ min;
}


I need a replacement for PHP's rand() function that uses a cryptographically strong random number generator.

The openssl_random_pseudo_bytes() function gets you access to the strong random number generator, but it outputs its data as a byte string. Instead, I need an integer between 0 and X.

I imagine the key is to get the output of openssl_random_pseudo_bytes() into an integer, then you can do any math on it that you need to. I can think of a few "brute force" ways of converting from a byte string to an integer, but I was hoping for something ... elegant.

解决方案

Using provided suggestions, I've created a drop-in replacement for rand() using OpenSSL. I'll include it here for posterity.

The $pedantic option gives bias-free results by starting over when results won't be evenly distributed across the possible range.

function crypto_rand($min,$max,$pedantic=True) {
    $diff = $max - $min;
    if ($diff <= 0) return $min; // not so random...
    $range = $diff + 1; // because $max is inclusive
    $bits = ceil(log(($range),2));
    $bytes = ceil($bits/8.0);
    $bits_max = 1 << $bits;
    // e.g. if $range = 3000 (bin: 101110111000)
    //  +--------+--------+
    //  |....1011|10111000|
    //  +--------+--------+
    //  bits=12, bytes=2, bits_max=2^12=4096
    $num = 0;
    do {
        $num = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes))) % $bits_max;
        if ($num >= $range) {
            if ($pedantic) continue; // start over instead of accepting bias
            // else
            $num = $num % $range;  // to hell with security
        }
        break;
    } while (True);  // because goto attracts velociraptors
    return $num + $min;
}

这篇关于将rand()替换为openssl_random_pseudo_bytes()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆