I would like to generate a secure random integer between $min and $max in PHP5.6. Both rand() and mt_rand() in PHP are considered not to be Cryptographically-Secure.
From the docs:
Caution
This function does not generate cryptographically secure values, and should not be used for cryptographic purposes. If you need a cryptographically secure value, consider using random_int(), random_bytes(), or openssl_random_pseudo_bytes() instead.
PHP 7 adds random_int() (docs), which fits my use-case perfectly:
random_int — Generates cryptographically secure pseudo-random integers
But how can this functionality be attained in PHP 5.6?
My naive attempt was this:
<?php
function secure_rand($min, $max)
{
return (unpack("N", openssl_random_pseudo_bytes(4)) % ($max - $min)) + $min;
}
But I seem to always get "2" when calling secure_rand(1, 100). I have also read that using a modulus operation in this way can create a bias. How can I emulate random_int() in PHP 5.6?
Might I introduce you to random_compat, which polyfills random_bytes() and random_int() in PHP 5 projects? (Sidenote: among other projects, it's being picked up by Wordpress in 4.4.)
function secure_rand($min, $max)
{
return (unpack("N", openssl_random_pseudo_bytes(4)) % ($max - $min)) + $min;
}
Even if this was doing what you wanted it to do, this is a biased random number generator when ($max - $min) is not an even power of 2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With