Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
510 views
in Technique[技术] by (71.8m points)

php - replace rand() with openssl_random_pseudo_bytes()

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...