Генератор случайных чисел

Статус
В этой теме нельзя размещать новые ответы.

Abliganto

Постоялец
Регистрация
30 Ноя 2009
Сообщения
111
Реакции
47
Хочу поделиться опытом об особенностях функций rand в PHP. Хочется сразу заметить, что на самом деле это псевдо-случайные числа и сейчас вы увидите, что вовсе не случайные.

Каждый раз перед генерацией случайного числа запускается ф-ция srand, которая устанавливает seed. На основе этого сида будет получено якобы случайное число. У одного сида выходит всегда одно и то же число!

PHP:
<?php
srand( 3 );
echo rand(); // всегда вернёт 7040

Причём, сидом для следующего вызова любой rand или mt_rand ф-ции становится предыдущее случайное число, т.е. 7040, значит след. случайное число будет 26041.

PHP:
<?php
srand( 3 );
echo rand(); // всегда вернёт 7040
echo rand(); // всегда вернёт 26041

Хватит лирики, чем это опасно. Ф-ция array_rand для получения случайного значения использует сид установленный srand(). Т.е. если вы генерируете к примеру сайт - в итоге могут получиться несколько совершенно одинаковых сайтов если вдруг совпадут сиды! Причём, совпасть нужно лишь первому сиду, все остальные rand'ы будут возвращать одно и то же.
По-этому перед каждым запуском рандом-фций советую делать srand( mt_rand() ); и перед mt_rand вызывать mt_srand() без параметров, чтобы не использовалось предыдущее полученое значение.

Буду рад услышать любые замечания/дополнения.
 
Т.е. если вы генерируете к примеру сайт - в итоге могут получиться несколько совершенно одинаковых сайтов
Это как?

Т.е. такой скрипт может вернуть несколько одиноковых случайных величин подряд?
PHP:
for ($i=0;$i<999999;$i++){
echo rand();
}

Приведи плиз пример опасного скрипта.
 
Буду рад услышать любые замечания/дополнения.
ну, хорошо бы прочитать в учебнике или хотя бы мануал про функцию srand.
+ некоторые люди ругают функцию rand за плохое качество генерируемых значений. И советуют использовать mt_rand
 
Это как?
Т.е. такой скрипт может вернуть несколько одиноковых случайных величин подряд?
PHP:
for ($i=0;$i<999999;$i++){
echo rand();
}
Приведи плиз пример опасного скрипта.

Он может вернуть не несколько, а все чётко известные величины.

Перед первым вызовом любой rand функции автоматически вызывается srand(). Без параметра он установит сид (число) от 1 (а может и от 0) до числа, которое вернёт ф-ция getrandmax() на 32-битном Windows это число int 32767. Т.е. вероятность того, что 2 раза будет сгенерирован один и тот же сид достаточно велика.

К примеру, если сид выпадет в цифру 3, то результат
PHP:
<?php
srand( 3 );
for ($i=0;$i<10;$i++){
echo rand() . '<br>';
}

будет

Код:
7040
26041
24062
6495
28588
9333
23562
27771
23192
4849
Так что все якобы рандомы будут всегда одни и те же :) Если перед каждым вызовом ф-ции rand() вызывать srand(), можно надеяться на какой-то рандом :)

Я за 10 лет практики только недавно об этом узнал, когда у меня сгенерировалось несколько одинаковых 1 в 1 массива данных. Век живи, век учись :)
 
Он может вернуть не несколько, а все чётко известные величины.
Понятно. Сам не ожидал, что в пхп такой генератор. Если по сгенерированному значению можно узнать следующее, то это очень опасно... К примеру если такой генератор использовать в казино:D, в рулетке )
 
Давно известная проблема и присуща во всех ЯП.
Хорошие генераторы рандома стоят хороших денег и не программны, а аппаратны.
 
Понятно. Сам не ожидал, что в пхп такой генератор. Если по сгенерированному значению можно узнать следующее, то это очень опасно... К примеру если такой генератор использовать в казино:D, в рулетке )
Ну, не факт. Опасность заключается в том, что вся последовательность рандомов может оказаться одинаковой!

Если кому интересно, можно почитать интересные заметки на тему рандома в PHP.


Будьте осторожны! :)
 
Используйте функцию:
PHP:
int mt_rand ( int $min , int $max )
 
Ну, не факт. Опасность заключается в том, что вся последовательность рандомов может оказаться одинаковой!
Будьте осторожны! :)
Не может оказаться, а 100% окажется! В этом и фишка srand(), мегаполезная фишка на самом деле. :)
В языках, где ее нет, бывает самому приходится писать генератор ПСЧ и это еще тот заеб.

Для параноиков надо ставить в начале srand(microtime(1)) или srand(time() + getmypid()) - и все будет случайно каждый раз :)

PS: Вообще-то srand() для того и существует, чтоб можно было последовательность случайных чисел прокрутить еще раз. Иначе смысла б в такой функции не было.
2 Hi-tech: И mt_srand() кстати тоже есть. И тоже действует аналогично.
 
Не может оказаться, а 100% окажется! В этом и фишка srand(), мегаполезная фишка на самом деле. :)
В языках, где ее нет, бывает самому приходится писать генератор ПСЧ и это еще тот заеб.
Для параноиков надо ставить в начале srand(microtime(1)) или srand(time() + getmypid()) - и все будет случайно каждый раз :)
PS: Вообще-то srand() для того и существует, чтоб можно было последовательность случайных чисел прокрутить еще раз. Иначе смысла б в такой функции не было.
Странно, что в документации по PHP ни слова об этом не сказано (может в комментах где-то и освящается). Можно сказать, что документация вводит в заблуждение, т.к. говорит, что перед каждым вызовом rand ф-ций srand вызывается автоматически, и я всегда наивно предполагал, что рандом всегда будет рандом.

Интересно, как обстоят дела с рандомом в дор-генераторах :)
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху