Here's a drop-in replacement for rand() using OpenSSL as your PRNG:
<?php
function crypto_rand($min,$max) {
$range = $max - $min;
if ($range == 0) return $min; // not so random...
$length = (int) (log($range,2) / 8) + 1;
return $min + (hexdec(bin2hex(openssl_random_pseudo_bytes($length,$s))) % $range);
}
?>
openssl_random_pseudo_bytes
(PHP 5 >= 5.3.0)
openssl_random_pseudo_bytes — Generate a pseudo-random string
Description
bool openssl_random_pseudo_bytes
( string $length
, string $strong
)
openssl_random_pseudo_bytes() returns a string with length caracters. It also indicates if it has used a strong algorithm to produce those pseudo-random bytes in the second argument.
Parameters
- length
-
The length of the desired string. Must be a positive integer. PHP will try to cast this parameter to a non-null integer to use it.
- strong
-
If a strong algorithm was used, or not, as a boolean. This parameter will be NULL if an error occurrs.
Return Values
Returns the generated string in case of success, or FALSE on failure.
Examples
Example #1 openssl_random_pseudo_bytes() example
<?php
for ($i = -1; $i < 5; $i++) {
var_dump(bin2hex(openssl_random_pseudo_bytes($i, $strong)));
var_dump($strong);
}
?>
The above example will output something similar to:
string(0) "" NULL string(0) "" NULL string(2) "f6" bool(true) string(4) "8999" bool(true) string(6) "c202c9" bool(true) string(8) "45261b8f" bool(true)
openssl_random_pseudo_bytes
Tyler Larson
22-Aug-2009 12:18
22-Aug-2009 12:18
Tyler Larson
21-Aug-2009 11:29
21-Aug-2009 11:29
If you don't have this function but you do have OpenSSL installed, you can always fake it:
<?php
function openssl_random_pseudo_bytes($length) {
$length_n = (int) $length; // shell injection is no fun
$handle = popen("/usr/bin/openssl rand $length_n", "r");
$data = stream_get_contents($handle);
pclose($handle);
return $data;
}
?>
