2008-08-08 2 views
17

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

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

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

$i = 0; 

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

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

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

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

+0

В php7 есть новая функция, которая [делает именно то, что вам нужно] (http://stackoverflow.com/a/31444887/1090562). – 2015-07-16 03:28:00

ответ

21

Добавление, умножение или усечение плохого случайного источника даст вам плохой случайный результат. См. Introduction to Randomness and Random Numbers для пояснения.

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

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

3

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

+0

Sooooo, с сегодняшними быстрыми многоядерными компьютерами, у вас есть довольно солидный шанс повторно использовать семя несколько раз? Humongous red flag - вы изобретаете квадратное колесо, даже `srand()` без аргументов делает более качественную («более случайную») работу. – Piskvor 2012-06-18 17:59:52

5

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

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

4

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

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

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

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

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

2

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

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

openssl_random_pseudo_bytes(...) 

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

1

Новый PHP7 есть функция, которая делает именно то, что вам нужно: он генерирует cryptographically secure pseudo-random integers.

int random_int (int $min , int $max) 

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

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