Мне нужно создать случайные целые числа между значениями 0 и 10 000 000, и мне понадобится несколько миллионов таких чисел. Цифры должны быть как можно ближе к CSPRNG, так как, например, кто-то должен читать, поэтому 1 миллион из 2 миллионов таких чисел, которые они считают неосуществимыми, выработать оставшиеся 1 миллион номеров.
После некоторых исследований я пришел к выводу, что с помощью имеющихся у меня инструментов (Unix / PHP) использование / dev / urandom будет моим лучшим выбором.
Я столкнулся с этим решением:
// equiv to rand, mt_rand // returns int in *closed* interval [$min,$max] function devurandom_rand($min = 0, $max = 0x7FFFFFFF) { $diff = $max - $min; if ($diff < 0 || $diff > 0x7FFFFFFF) { throw new RuntimeException("Bad range"); } $bytes = mcrypt_create_iv(4, MCRYPT_DEV_URANDOM); if ($bytes === false || strlen($bytes) != 4) { throw new RuntimeException("Unable to get 4 bytes"); } $ary = unpack("Nint", $bytes); $val = $ary['int'] & 0x7FFFFFFF; // 32-bit safe $fp = (float) $val / 2147483647.0; // convert to [0,1] return round($fp * $diff) + $min; }
Источник: https://codeascraft.com/2012/07/19/better-random-numbers-in-php-using-devurandom/
Учитывая, что мне нужно создать большое количество случайных чисел, буду ли я лучше писать / dev / urandom к файлу, а затем читать 3 байта (2 ^ 24 = 16 миллионов) за раз и преобразовывать в целое число?
Является ли решение подходящим для моих нужд?
Когда PHP 7 выходит, у него есть новая функция random_int()
которая служит этой цели.
Если вам это нужно сегодня (т.е. в проекте PHP 5), проверьте random_compat .
По крайней мере, посмотрите, как random_int()
реализуется в random_compat. Среди других причин он по-прежнему работает для диапазонов, больших, чем PHP_INT_MAX
. (Да, он использует /dev/urandom
.)
Демо: http://3v4l.org/VJGCb