将rand()替换为openssl_random_pseudo_bytes() [英] replace rand() with 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屋!