В чем недостаток mt_rand? - PullRequest
       25

В чем недостаток mt_rand?

26 голосов
/ 18 октября 2011

Какое определение уклона в:

Распределение mt_rand () возвращаемых значений смещено в сторону четных чисел в 64-битных сборках PHP, когда max превышает 2 ^ 32.

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

Кроме того, mt_rand() - это , заявленное , что в четыре раза быстрее, чем rand(), просто добавив три символа впереди!

Если mt_rand доступно, в чем его недостаток?

Ответы [ 2 ]

57 голосов
/ 18 октября 2011

mt_rand использует алгоритм Mersenne Twister , который намного лучше, чем LCG , обычно используемый rand. Например, период LCG является жалким 2 32 , тогда как период mt_rand равен 2 19937 - 1. Кроме того, все значения, генерируемые LCG, будут лежат на линиях или плоскостях при построении в многомерном пространстве. Кроме того, это не только практически осуществимо, но и относительно легко определить параметры LCG. Единственное преимущество, которым обладают LCG - это, возможно, немного быстрее, но в масштабе, который совершенно не имеет значения при кодировании в php.

Однако mt_rand - это , не пригодный для криптографических целей (генерация токенов, паролей или криптографических ключей).

Если вам нужна криптографическая случайность, используйте random_int в php 7. В более старых версиях php читайте из /dev/urandom или /dev/random в операционной системе, соответствующей POSIX.

8 голосов
/ 18 октября 2011

Причудливость распределения, которую вы цитировали, актуальна только тогда, когда диапазон случайных чисел, который вы генерируете, больше чем 2 ^ 32.Это 4294967296.

Если вы работаете с такими большими числами, и вам нужно, чтобы они были рандомизированы, то, возможно, это является причиной для пересмотра использования mt_rand().Однако, если вы работаете с числами, меньшими, чем это, это не имеет значения.

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

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

Разница между rand() и mt_rand() намного больше, чем "просто три дополнительных символа".Это совершенно разные вызовы функций, и они работают совершенно по-разному.Точно так же, как вы не ожидаете, что print() и print_r() будут похожими.

mt_rand() получает свое имя от алгоритма "Mersene Twister", который используется для генерации случайных чисел.Известно, что этот алгоритм является быстрым, эффективным и высококачественным генератором случайных чисел, поэтому он доступен в PHP.

Старая функция rand() использует генератор случайных чисел операционной системы, создаваясистемный вызов.Это означает, что он использует любой генератор случайных чисел, который используется по умолчанию в используемой операционной системе.Как правило, генератор случайных чисел по умолчанию использует гораздо более медленный и старый алгоритм, поэтому утверждается, что my_rand() быстрее, но он будет варьироваться от системы к системе.

Поэтому для практически всех применений mt_rand() это лучшая функция для использования, чем rand().

Вы говорите «при условии, что mt_rand() доступно», но так будет всегда, поскольку оно было введено еще в PHP4.

...