SHA512 для генерации случайных чисел в PHP

Я заполняю массив случайными числами, используя $blockhash[$i] = rand().time().rand()

Затем для каждого случайного числа в этом массиве я вычисляю соответствующий SHA512

 $SecretKey = "60674ccb549f1988439774adb82ff187e63a2dfd403a0dee852e4e4eab75a0b3"; $sha = hash_hmac('sha512', $value, $SecretKey); 

Раздели это:

 $pool = str_split($sha, 2); 

Затем я получаю первое число из массива $ pool, конвертирую hex в dec и ограничивая его в пределах 1 и 50:

 $dec = hexdec($pool[0]) % 50 + 1; 

Проблема в том, что цифры не такие случайные, и я не знаю почему. Я подсчитываю частоту для каждого номера от 1 до 50, но цифры 1,2,3,4,5 и 6 чаще появляются, чем другие. См. График

введите описание изображения здесь

Почему это происходит и как это исправить? Благодаря!

Вы получаете 1-6 чаще, потому что вы получаете две шестнадцатеричные цифры из хэша. Это один байт, поэтому он может хранить значения от 0 до 255 . Затем вы используете modulo 50 . В результате вы получаете диапазоны 0-49 , 50-99 , 100-149 , 150-199 , 200-249 и … 250-255 . Этот последний отвечает за дополнительную распространенность 1-6 в ваших результатах.

Решение: просто используйте mt_rand(1,50);

[редактировать]

Если вам действительно нужно преобразовать число из диапазона 0-255 в диапазон 1-50, решение будет масштабироваться и округлять.

 $number = round(($byteValue)/(255/49))+1; 

два шестнадцатеричных символа, которые вы преобразуете в десятичный, будут находиться в диапазоне 0-255. вы измените это на 50 и добавьте 1, сделав 1-6 (диапазон (0-5) +1), 6 раз по 1-256, а каждый другой номер – всего 5 раз. Это приведет к увеличению на 20% роста этих цифр.

Ни rand() ни mt_rand() генерируют действительно случайные значения.

Как говорится в руководстве:

Эта функция не генерирует криптографически безопасные значения и не должна использоваться для криптографических целей. Если вам требуется криптографически безопасное значение, openssl_random_pseudo_bytes() вместо этого использовать openssl_random_pseudo_bytes() .

См. Better Random Generating PHP для вопроса StackOverflow, который указывает ту же проблему и имеет некоторые хорошие ответы.