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

Тема в разделе "PHP", создана пользователем Abliganto, 8 мар 2010.

Статус темы:
Закрыта.
Модераторы: latteo
  1. Abliganto

    Abliganto Постоялец

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

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

    PHP:
    <?php
    srand
    );
    echo 
    rand(); // всегда вернёт 7040
    Причём, сидом для следующего вызова любой rand или mt_rand ф-ции становится предыдущее случайное число, т.е. 7040, значит след. случайное число будет 26041.

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

    Буду рад услышать любые замечания/дополнения.
     
  2. Nevep

    Nevep Постоялец

    Регистр.:
    16 дек 2009
    Сообщения:
    59
    Симпатии:
    8
    Это как?

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

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    883
    Симпатии:
    540
    ну, хорошо бы прочитать в учебнике или хотя бы мануал про функцию srand.
    + некоторые люди ругают функцию rand за плохое качество генерируемых значений. И советуют использовать mt_rand
     
  4. Abliganto

    Abliganto Постоялец

    Регистр.:
    30 ноя 2009
    Сообщения:
    111
    Симпатии:
    46
    Он может вернуть не несколько, а все чётко известные величины.

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

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

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

    Я за 10 лет практики только недавно об этом узнал, когда у меня сгенерировалось несколько одинаковых 1 в 1 массива данных. Век живи, век учись :)
     
  5. Nevep

    Nevep Постоялец

    Регистр.:
    16 дек 2009
    Сообщения:
    59
    Симпатии:
    8
    Понятно. Сам не ожидал, что в пхп такой генератор. Если по сгенерированному значению можно узнать следующее, то это очень опасно... К примеру если такой генератор использовать в казино:D, в рулетке )
     
  6. PHP_Master

    PHP_Master

    Регистр.:
    3 фев 2008
    Сообщения:
    2.647
    Симпатии:
    590
    Давно известная проблема и присуща во всех ЯП.
    Хорошие генераторы рандома стоят хороших денег и не программны, а аппаратны.
     
  7. Abliganto

    Abliganto Постоялец

    Регистр.:
    30 ноя 2009
    Сообщения:
    111
    Симпатии:
    46
    Ну, не факт. Опасность заключается в том, что вся последовательность рандомов может оказаться одинаковой!

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

    http://raz0r.name/articles/predskazyvaem-sluchajnye-chisla-v-php/
    http://www.xakep.ru/post/46797/default.asp (+ ссылки к статье)


    Будьте осторожны! :)
     
  8. Hi-tech

    Hi-tech Создатель

    Регистр.:
    4 авг 2009
    Сообщения:
    39
    Симпатии:
    8
    Используйте функцию:
    PHP:
    int mt_rand int $min int $max )
     
  9. venetu

    venetu

    Регистр.:
    28 мар 2007
    Сообщения:
    735
    Симпатии:
    261
    Не может оказаться, а 100% окажется! В этом и фишка srand(), мегаполезная фишка на самом деле. :)
    В языках, где ее нет, бывает самому приходится писать генератор ПСЧ и это еще тот заеб.

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

    PS: Вообще-то srand() для того и существует, чтоб можно было последовательность случайных чисел прокрутить еще раз. Иначе смысла б в такой функции не было.
    2 Hi-tech: И mt_srand() кстати тоже есть. И тоже действует аналогично.
     
  10. Abliganto

    Abliganto Постоялец

    Регистр.:
    30 ноя 2009
    Сообщения:
    111
    Симпатии:
    46
    Странно, что в документации по PHP ни слова об этом не сказано (может в комментах где-то и освящается). Можно сказать, что документация вводит в заблуждение, т.к. говорит, что перед каждым вызовом rand ф-ций srand вызывается автоматически, и я всегда наивно предполагал, что рандом всегда будет рандом.

    Интересно, как обстоят дела с рандомом в дор-генераторах :)
     
Статус темы:
Закрыта.