Comments 22
Проблема с RAND_MAX — мелочи :-) Как «радует» разнообразием используемых алгоритмов для получения «случайных» чисел всеми любимый PHP — отдельная песня! Там начиная от самых тупых LCRNG через Type3 до MersenneTwister. А над ними еще 2 функции стоят. И все это по разному работает на разных платформах (Win, Linux, BSD) и с разными патчами/настройками.
+1
Интересно =)
расскажите подробнее, пожалуйста
расскажите подробнее, пожалуйста
+1
Можно написать простенький PHP-скрипт, который сделает srand(0) и выведет 10 результатов rand(). В идеале, каждый запуск должен выводить одни и те же числа, в статье написано почему. В реальности, на некоторых системах будет так, а на некоторых будут разные результаты. Это — игнорирование srand и зависит от патчей безопасности.
Относительно систем с повторяющимися результатами: скрипт выдаст разные числа на Linux, BSD и Windows. В никсах обычно используется Glibc-Type3 генератор, в винде — LCRNG из Glibc, да еще и RAND_MAX маленький. В BSD тоже Type3, но свой.
Это мы рассматривали rand(void), но есть еще rand(min, max), который использует результаты rand(). А еще есть array_rand (если не путаю имя), тоже из rand() берущий данные.
Особняком стоит MersenneTwister (функции mt_*), но там я еще не разбирался. Вроде, при патчах он заменяет Type3 и LCRNG.
Относительно систем с повторяющимися результатами: скрипт выдаст разные числа на Linux, BSD и Windows. В никсах обычно используется Glibc-Type3 генератор, в винде — LCRNG из Glibc, да еще и RAND_MAX маленький. В BSD тоже Type3, но свой.
Это мы рассматривали rand(void), но есть еще rand(min, max), который использует результаты rand(). А еще есть array_rand (если не путаю имя), тоже из rand() берущий данные.
Особняком стоит MersenneTwister (функции mt_*), но там я еще не разбирался. Вроде, при патчах он заменяет Type3 и LCRNG.
0
Интересная статья, будем надеяться на продолжение. Интересно, что за гипотеза относительно провалившихся тестов TestU01
+4
Спасибо! Продолжение про ГПСЧ пока не планирую, но от меня будут другие статьи. А ещё мои коллеги черкнули мне, что я забыл про RNG из состава Intel MKL, каюсь, да. Но, с другой стороны, кто лучше напишет про MKL, как не сами его авторы, так что сам жду ответного поста от них.
Ответ про гипотезу чуть ниже.
Ответ про гипотезу чуть ниже.
0
Изобретать своё конечно полезно, но гораздо проще взять любой современный хэш\алгоритм шифрования и использовать его как сидированный ГПСЧ с гарантированной рендомностью. Или Fortuna если совсем паранойя объяла
+2
Было бы неплохо помимо минусов прочитать какую нибудь аргументацию
0
Начните с себя и аргументируйте чем предложенное вами лучше.
-2
Проблема в сидировании.
-1
Точнее, в определении качества сида.
Я вот столкнулся на практике, программируя замену window.crypto.getRandomValues(…) для устаревших или запроприетаренных браузеров.
Так вот в браузерах (да и вообще много где) нет надежных источников энтропии, кроме пользовательского ввода. И тот — не вполне надежен, есть нюянсы короче.
Плодами моих усилий стал небольшой, но полезный скриптик
Я вот столкнулся на практике, программируя замену window.crypto.getRandomValues(…) для устаревших или запроприетаренных браузеров.
Так вот в браузерах (да и вообще много где) нет надежных источников энтропии, кроме пользовательского ввода. И тот — не вполне надежен, есть нюянсы короче.
Плодами моих усилий стал небольшой, но полезный скриптик
0
Хотя, чего я вам рассказываю, судя по вашему профилю, вы и так в курсе )
0
Проблема в сидировании.
Мсье намекает на существование алгоритмов, которые не надо сидировать?)
Я так понимаю, для задач «опытов» можно обойтись обычными getTickCount или подобным. Сид всегда гарантированно разный, а тесты всегда будут пройдены (рассматриваем случай использования сида как, например, ключа для шифрования быстрого поточного алгоритма вроде RC4. Он хоть уже и не особо стойкий, но ни чуть не медленней предложенного тут варианта).
Ну а для криптографии да, тут другой подход нужен. Собирать энтропию это искусство )
0
С того, что не надо изобретать велосипед, если есть существующие DRBG или PRF, удовлетворяющие вашим требованиям.
+2
> Изобретать своё конечно полезно,
Ничего своего тут и не изобретено — алгоритмы давно известные, параметры для них подобраны не нами.
> но гораздо проще взять любой современный хэш\алгоритм шифрования
Он будет существенно сложнее, чем a*x + c (поправьте, если это не так). Это значит, что придётся или писать нечто более сложное самому, или завязываться на внешние библиотеки типа OpenSSL, внимательно сидеть и думать над их лицензией, над экспортным контролем и т.п.
> с гарантированной рендомностью
Ничто не гарантированно, как известно. Хочется знать ограничения выбранного решения, а не надеяться на авось.
> если совсем паранойя объяла
Тут дело не в том. Для нашей ситуации даже последовательность 1, 2,3, 4… подошла бы лучше, чем rand(), потому что она повторяема.
Ничего своего тут и не изобретено — алгоритмы давно известные, параметры для них подобраны не нами.
> но гораздо проще взять любой современный хэш\алгоритм шифрования
Он будет существенно сложнее, чем a*x + c (поправьте, если это не так). Это значит, что придётся или писать нечто более сложное самому, или завязываться на внешние библиотеки типа OpenSSL, внимательно сидеть и думать над их лицензией, над экспортным контролем и т.п.
> с гарантированной рендомностью
Ничто не гарантированно, как известно. Хочется знать ограничения выбранного решения, а не надеяться на авось.
> если совсем паранойя объяла
Тут дело не в том. Для нашей ситуации даже последовательность 1, 2,3, 4… подошла бы лучше, чем rand(), потому что она повторяема.
-1
Помню эти таблицы случайных чисел по университету)) Использовали при изучении полного факторного эксперимента.
0
Мелькнула мысль, что если ГПСЧ выдает полностью состояние (допустим 32 бита), либо инъективную функцию от состояния, то его можно с большой вероятностью «отличить от рандома» простым общим статистическим тестом — у «правильного» рандома из примерно 2**17 выходов хотя бы два должны совпасть. У описанного ГПСЧ совпасть выходы так быстро не могут, т.к. тогда образуется период и его тоже легко вычислить.
Про криптографическую стойкость таких ГПСЧ говорить нет смысла, но это может быть проблемой и для различных экспериментов со «случайными» данными.
Про криптографическую стойкость таких ГПСЧ говорить нет смысла, но это может быть проблемой и для различных экспериментов со «случайными» данными.
+2
По этой причине в настоящее время генераторы с размером состояния 32 бита (и периодом 2^32) уже неактуальны.
> у «правильного» рандома из примерно 2**17 выходов хотя бы два должны совпасть
Ваш анализ правильный (и подобный тест наверняка включён в TestU01), но нужно учесть объёмы памяти и времени, необходимый для его проведения, ведь надо хранить все уже сгенерированные числа и сравнивать новые поступающие с каждым из них. Для 32-битного генератора это будет порядка 2^17 * 4 = 0.5 Мбайт, а вот для 64-битного, по аналогии, это будут уже гигабайты. Ну и время будет расти экспоненциально.
> у «правильного» рандома из примерно 2**17 выходов хотя бы два должны совпасть
Ваш анализ правильный (и подобный тест наверняка включён в TestU01), но нужно учесть объёмы памяти и времени, необходимый для его проведения, ведь надо хранить все уже сгенерированные числа и сравнивать новые поступающие с каждым из них. Для 32-битного генератора это будет порядка 2^17 * 4 = 0.5 Мбайт, а вот для 64-битного, по аналогии, это будут уже гигабайты. Ну и время будет расти экспоненциально.
+1
В этом плане наука статистика очень хорошо отражает суть позитивизма в естественнонаучном принципе познания — нельзя доказать гипотезу, но можно попытаться её опровергнуть.
В нашем случае можно попытаться огромным числом различных способов найти неслучайность в выходе ГПСЧ и потерпеть неудачу, при этом зная, что это — именно ГПСЧ. Этим мы не докажем случайность последовательности, но и не опровергнем её. Когда, например, изменятся инструменты (новые алгоритмы, больше памяти, быстрее компы), доказательство неслучайности, может быть, и будет найдено, вот тогда можно будет сказать «ага!» и выкинуть конкретный алгоритм ГПСЧ на свалку.
Очень многие проблемы возникают как раз из-за непонимания этого основного принципа как статистики, так и строгой науки в целом.
Моя гипотеза, почему некоторые тесты из TestU01 стабильно не проходят, связана с особенностями эксперимента и организации кода. А именно, оригинальный фреймворк заточен (или это я только это в нём нашёл) на тестирование 32-битных (а точнее, int) генераторов. Хотя отдельный класс для тестирования 64-битных целых (а точнее long int) там есть, похоже, что он не очень отлажен — у меня падал с ошибками, которые я хоть и исправил, но не отладил до конца (если будут силы, свяжусь с автором и попрошу совета). Однако есть работающий класс для тестирования 64-битных чисел с плавающей запятой, к коим я и привёл выводы своих генераторов (к отрезку от 0.0 до 1.0). В double-ах всего 53 бита мантиссы, т.е. 11 бит исходного числа мы теряем. Вот здесь и лежит слабое место, и возможно, что тесты это «почувствовали».
В нашем случае можно попытаться огромным числом различных способов найти неслучайность в выходе ГПСЧ и потерпеть неудачу, при этом зная, что это — именно ГПСЧ. Этим мы не докажем случайность последовательности, но и не опровергнем её. Когда, например, изменятся инструменты (новые алгоритмы, больше памяти, быстрее компы), доказательство неслучайности, может быть, и будет найдено, вот тогда можно будет сказать «ага!» и выкинуть конкретный алгоритм ГПСЧ на свалку.
Очень многие проблемы возникают как раз из-за непонимания этого основного принципа как статистики, так и строгой науки в целом.
Моя гипотеза, почему некоторые тесты из TestU01 стабильно не проходят, связана с особенностями эксперимента и организации кода. А именно, оригинальный фреймворк заточен (или это я только это в нём нашёл) на тестирование 32-битных (а точнее, int) генераторов. Хотя отдельный класс для тестирования 64-битных целых (а точнее long int) там есть, похоже, что он не очень отлажен — у меня падал с ошибками, которые я хоть и исправил, но не отладил до конца (если будут силы, свяжусь с автором и попрошу совета). Однако есть работающий класс для тестирования 64-битных чисел с плавающей запятой, к коим я и привёл выводы своих генераторов (к отрезку от 0.0 до 1.0). В double-ах всего 53 бита мантиссы, т.е. 11 бит исходного числа мы теряем. Вот здесь и лежит слабое место, и возможно, что тесты это «почувствовали».
0
Sign up to leave a comment.
Случайные числа и детерминистичная симуляция