Лучшая случайная генерация PHP

Я знаю, что простое использование rand() предсказуемо, если вы знаете, что делаете, и имеете доступ к серверу.

У меня есть проект, который сильно зависит от выбора случайного числа, которое является настолько непредсказуемым, насколько это возможно. Поэтому я ищу предложения, будь то другие встроенные функции или пользовательские функции, которые могут генерировать лучшее случайное число.

Я использовал это для небольшого теста:

$i = 0;

while($i < 10000){
    $rand = rand(0, 100);

    if(!isset($array[$rand])){
        $array[$rand] = 1;
    } else {
        $array[$rand]++;
    }

    sort($array);
    $i++;
}

Я обнаружил, что результаты распределяются равномерно, и существует нечетная закономерность в отношении того, сколько раз генерируется каждое число.

Ответов (6)

Решение

Добавление, умножение или усечение плохого случайного источника даст вам плохой случайный результат. См. Объяснение в разделе Введение в случайность и случайные числа .

Вы правы насчет функции PHP rand (). См. Второй рисунок, посвященный статистическому анализу, для наглядной иллюстрации. (Первая цифра поразительна, но она нарисована Скоттом Адамсом, а не с помощью rand ()).

Одно из решений - использовать настоящий генератор случайных чисел, такой как random.org . Другой, если вы используете Linux / BSD / и т. Д. использовать / dev / random . Если случайность критически важна, вам придется использовать аппаратный генератор случайных чисел .

Другой способ получения случайных чисел, похожий по концепции на получение UUID

Версия PHP 5.3 и выше

openssl_random_pseudo_bytes(...)

Или вы можете попробовать следующую библиотеку, используя RFC4122

Вариация @KG с использованием миллисекунд с момента EPOCH в качестве начального числа для rand?

random.org имеет API, к которому вы можете получить доступ через HTTP.

RANDOM.ORG - это настоящий сервис случайных чисел, который генерирует случайность с помощью атмосферного шума.

Я бы опасался впечатления случайности: было много экспериментов, в которых люди выбирали менее случайное распределение. Кажется, что ум не очень хорош в создании или оценке случайности.

В Fourmilab есть хорошие статьи о случайности , включая еще один настоящий генератор случайных чисел . Возможно, вы могли бы получить случайные данные с обоих сайтов, поэтому, если один из них не работает, у вас все еще есть другой.

Fourmilab также предоставляет тестовую программу для проверки случайности. Вы можете использовать его для проверки различных программ myRand ().

Что касается вашей последней программы, если вы генерируете 10000 значений, почему бы вам не выбрать окончательное значение среди 10 тысяч? Вы ограничиваете себя подмножеством. Кроме того, это не сработает, если ваши $ min и $ max больше 10000.

В любом случае, необходимая вам случайность зависит от вашего приложения. rand () подойдет для онлайн-игры, но не подходит для криптографии (все, что не было тщательно проверено статистическими программами, в любом случае не подойдет для криптографии). Ты будешь судьей!

В новом PHP7 есть функция, которая делает именно то, что вам нужно: она генерирует криптографически безопасные псевдослучайные целые числа.

int random_int ( int $min , int $max )

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

Для более подробного объяснения ГПСЧ и CSPRNG (и их различий), а также того, почему ваш исходный подход на самом деле является плохой идеей, прочитайте мой еще один очень похожий ответ .