Reading /dev/urandom and generating a random integer
I am trying to create a function that generates a random integer out of the bytes I get from /dev/urandom. I am doing this in PHP and it currently looks like:
public static function getRandomInteger($min, $max)
{
// First we need to determine how many bytes we need to construct $min-$max range.
$difference = $max-$min;
$bytesNeeded = ceil($difference/256);
$r开发者_开发百科andomBytes = self::getRandomBytes($bytesNeeded);
// Let's sum up all bytes.
$sum = 0;
for ($a = 0; $a < $bytesNeeded; $a++)
$sum += ord($randomBytes[$a]);
// Make sure we don't push the limits.
$sum = $sum % ($difference);
return $sum + $min;
}
Everything works great except that I think it's not calculating the values exactly fair. For example, if you want to have a random value between 0 and 250, it receives one byte and mods it with 250 so the values of 0-6 are more likely to appear than the values of 7-250. What should I do to fix this?
a) If you don't need cryptographically secure random numbers, simply use mt_rand
. It will probably suffice for your needs.
b) If you want to stick with your algorithm: Do some remapping: return round($min + $sum / pow(256, $bytesNeeded) * ($max - $min))
.
c) As you can see, this requires round
ing. That will lead to a not perfectly uniform distribution, I think (though I am not sure about this). Probably the best way is to get the random number as a float and then scale it. Though I have no idea how you get a float from /dev/urandom
. That's why I stick with mt_rand
and lcg_value
.
I would read $difference
bytes from /dev/urandom mod $difference
and then add $min
Then make sure $max
isn't higher than that number.
精彩评论