о псевдослучайных числах в PHP

valyala

Новичок
о псевдослучайных числах в PHP

Вот несколько вопросов по поводу "случайных" чисел в ПХП, на которые хотелось бы увидеть ваш ответ:

1) Чем отличается функция [m]rand[/m] от [m]mt_rand[/m]?
2) Насколько "случайными" получаются последовательности чисел, генерируемых этими функциями?
3) От чего зависит эта "случайность"?
4) Можно ли предсказать следующее число в генерируемой последовательности по предыдущему?
5) Всегда ли равномерно распределение генерируемых чисел?
6) Безопасно ли использовать эти функции для генерации криптографических ключей, идентификаторов сессий, "циферок" на картинках? А что насчет интернет-казино?
7) Какова длина периода у этих функций?
8) Для чего нужны функции [m]srand[/m] и [m]mt_srand[/m]?
 

Найч

Алгоритмик :-)
Попробую не залазя в литературу.
2. "Очень случайные". Но эту последовательность можно повторить при соблюдении определенных условий.
3. Обычно стартуют от тиков процессора (счетчика команд, etc) и приводят к нужному диапазону
4. В общем случае - нет. Но см. п.2
5. На бесконечности - да.
6. С заданной степенью безопасности используют. Абсолютно - небезопасно.

1 и 8 написаны в мане.
 

valyala

Новичок
7) у mt_rand случайно не 2^19937-1
Может быть. Именно такой период упомянут на домашней страничке Mersenne Twister http://www.math.sci.hiroshima-u.ac.jp/~m-mat/eindex.html. А у rand() максимально возможный период равен 2^31 - 1.

2. "Очень случайные". Но эту последовательность можно повторить при соблюдении определенных условий.
А вот и нет! Последовательности чисел, генерируемые функциями rand() и mt_rand(), строго детерменированные. Они зависят лишь от начального вектора инициализации, передаваемого в srand() или mt_srand(). В обеих случаях длина этого вектора равна 31 бит. Поэтому, несмотря на громадный период mt_rand() (см. выше), в общем случае обе функции способны генерировать лишь 2^31 - 1 "различных" последовательностей псевдослучайных чисел.
Вообще-то, максимальная длина вектора инициализации для MT-генератора равна 624 байта, или 19968 бит, но разработчики ПХП решили "обрезать" его до 31 бита :)

3. Обычно стартуют от тиков процессора (счетчика команд, etc) и приводят к нужному диапазону
Случайность зависит лишь от алгоритма, используемого для генерации чисел. В rand() используется обычный линейный конгруэнтный генератор: X(i+1) = A*X(i) + B (mod 2^32), а в mt_rand() - вышеупомянутый Mersenne Twister.

4. В общем случае - нет. Но см. п.2
К сожалению, в общем случае - да. Для rand() это вообще не составляет труда - внимательно посмотри на формулу линейного конгруэнтного генератора. А для mt_rand() необходимо знать текущее значение вектора инициализации. Но, т.к. в ПХП его длина ограничена 31 битами, то ничто не мешает составить таблицу всех векторов инициализации для i-го числа, и по ней быстро находить следующее число.

5. На бесконечности - да.
Может быть. Я бы не был столь категоричным.

6. С заданной степенью безопасности используют. Абсолютно - небезопасно.
К сожалению, используют :(. Но ни rand(), ни mt_rand() в нынешнем виде не годятся для упомянутых задач.
 

Demiurg

Guest
valyala
мне кажется, что такому сильному человеку в математике, как ты, проще разобраться в исходниках и мануалах. Все алгоритмы и методы, обычно там описаны. А php вообще, как глупое создание использует системные функции.
 
Сверху