Я знаю, что использование rand()
предсказуемо, если вы знаете, что делаете, и имеете доступ к серверу.
У меня есть проект, который сильно зависит от выбора случайного числа, которое настолько непредсказуемо, насколько это возможно. Поэтому я ищу предложения, либо другие встроенные функции, либо функции пользователя, которые могут генерировать лучшее случайное число.
Я использовал это, чтобы сделать небольшой тест:
$i = 0; while($i < 10000){ $rand = rand(0, 100); if(!isset($array[$rand])){ $array[$rand] = 1; } else { $array[$rand]++; } sort($array); $i++; }
Я обнаружил, что результаты будут равномерно распределены, и существует нечетный шаблон количества раз, когда генерируется каждый номер.
Добавление, умножение или усечение плохого случайного источника даст вам плохой случайный результат. См. Введение в случайность и случайные числа для объяснения.
Вы правы в функции PHP rand (). См. Вторую цифру Статистического анализа для яркой иллюстрации. (Первая цифра поразительна, но она была нарисована Скоттом Адамсом, а не с графиком rand ()).
Одним из решений является использование истинного случайного генератора, такого как random.org . Другое, если вы используете Linux / BSD / etc. является использование / dev / random . Если случайность является критически важной, вам придется использовать аппаратный случайный генератор .
random.org имеет API, к которому вы можете получить доступ через HTTP.
RANDOM.ORG – это служба случайных чисел, которая генерирует случайность через атмосферный шум.
Я бы опасался впечатления от случайности: было много экспериментов, когда люди выбирали менее случайное распределение. Кажется, ум не очень хорош в производстве или оценке случайности.
Есть хорошие статьи о случайности в Fourmilab , включая другой настоящий случайный генератор . Возможно, вы можете получить случайные данные с обоих сайтов, поэтому, если у вас все еще есть, у вас все еще есть другой.
Fourmilab также предоставляет тестовую программу для проверки случайности. Вы можете использовать его для проверки различных программ myRand ().
Что касается вашей последней программы, если вы генерируете 10000 значений, почему бы вам не выбрать окончательное значение среди 10 тысяч? Вы ограничиваете себя подмножеством. Кроме того, он не будет работать, если ваши $ min и $ max превышают 10000.
В любом случае, случайность, в которой вы нуждаетесь, зависит от вашего приложения. rand () будет в порядке для онлайн-игры, но не ОК для криптографии (все, что не было тщательно проверено со статистическими программами, в любом случае не пригодно для криптографии). Ты будешь судьей!
Изменение на @KG, используя миллисекунды с EPOCH в качестве семени для rand?
Еще один способ получить случайные числа, похожие на концепцию получения UUID
PHP версии 5.3 и выше
openssl_random_pseudo_bytes(...)
Или вы можете попробовать следующую библиотеку, используя RFC4122
В новом PHP7 есть функция, которая делает именно то, что вам нужно: она генерирует криптографически безопасные псевдослучайные целые числа.
int random_int ( int $min , int $max )
Генерирует криптографические случайные целые числа, которые подходят для использования, когда критические (непредсказуемые) результаты имеют решающее значение (т. Е. Перетасовка колоды покера).
Для более подробного объяснения относительно PRNG и CSPRNG (и их разницы), а также почему ваш оригинальный подход на самом деле является плохими идеями, пожалуйста, прочтите мой другой очень похожий ответ .