Лучший случайный генерирующий PHP - PullRequest
19 голосов
/ 08 августа 2008

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

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

Я использовал это, чтобы сделать небольшой тест:

$i = 0;

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

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

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

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

Ответы [ 6 ]

21 голосов
/ 08 августа 2008

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

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

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

5 голосов
/ 08 августа 2008

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

RANDOM.ORG - это служба случайных чисел, которая генерирует случайность через атмосферный шум.

4 голосов
/ 09 августа 2008

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

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

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

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

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

2 голосов
/ 18 сентября 2013

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

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

openssl_random_pseudo_bytes(...)

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

2 голосов
/ 08 августа 2008

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

1 голос
/ 16 июля 2015

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

int random_int ( int $min , int $max )

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

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

...