Как вы проверяете что-то случайное? Или "достаточно случайно"? - PullRequest
4 голосов
/ 22 декабря 2010

Я должен вернуть случайную запись из моей базы данных.

Я написал функцию, и, поскольку я использую модуль random в Python, возможно, если я не использовал его глупо.

Теперь, как я могу написать модульпроверить, проверить, работает ли эта функция?В конце концов, если это хорошее случайное значение, вы никогда не узнаете.

Я не параноик, моя функция не настолько сложна, и стандартная библиотека Python в 1000 раз больше подходит для моих целей.Я не занимаюсь криптографией или чем-то критичным.Мне просто любопытно узнать, есть ли способ.

Ответы [ 6 ]

19 голосов
/ 22 декабря 2010

Есть несколько статистических тестов, перечисленных в RANDOM.ORG для проверки случайности .См. Последние два раздела связанной статьи.

Также, если вы можете получить копию Beautiful Testing , есть целая глава Джона Д. Кука , которая называется Проверка генератора случайных чисел .Он объясняет множество статистических методов, перечисленных в статье выше.Если вы действительно хотите узнать о ГСЧ, эта глава является действительно хорошей отправной точкой.Я сам написал об этом предмете, но Джон гораздо лучше объясняет его.

6 голосов
/ 23 декабря 2010

Вы не можете действительно сказать (см. Мультфильм).

Тем не менее, вы можете измерить энтропию вашего сгенерированного образца и сравнить ее с ожидаемой энтропией. Как уже упоминалось ранее, random.org делает несколько довольно умных тестов.

alt text

2 голосов
/ 22 декабря 2010

У вас есть два запутанных вопроса. Первая проблема - проверка того, что ваш случайный выбор работает. Заполнение вашего PRNG позволяет вам написать тест, который является детерминированным и о котором вы можете утверждать. Это должно дать вам уверенность в вашем коде, учитывая, что базовые функции соответствуют своим обязанностям (то есть random возвращает вам достаточно хороший поток случайных значений).

Второй вопрос, который вас беспокоит, это случайные функции python. Вы хотите отделить заботы вашего кода от концерта о случайной функции. Существует целый ряд тестов на случайность , которые вы можете прочитать о , но в конце концов, если вы не используете шифрование, я бы поверил, что разработчики Python сделали это правильно - довольно.

2 голосов
/ 22 декабря 2010

Вы можете заставить модульный тест вызывать функцию несколько раз и убедиться, что число столкновений достаточно мало. Например. если ваш случайный результат находится в диапазоне 1-1000000, вызовите функцию 100 раз и запишите результаты; затем проверьте, есть ли дубликаты. Если есть какие-либо (или более чем 1 столкновение, в зависимости от того, насколько вы боитесь ложного провала теста), тест проваливается Очевидно, не идеально, но поймать его, если вы случайное число от Дилберта: http://www.random.org/analysis/

1 голос
/ 22 сентября 2013

В дополнение к предыдущим ответам вы также можете смоделировать случайную функцию (например, с помощью библиотеки mock или mox ) и вернуть предопределенную последовательность значений, для которых известны результаты. Да, это не было бы истинным тестом для всех случаев, но вы можете проверить некоторые угловые случаи. В некоторых случаях такие тесты могут быть разумными.

0 голосов
/ 14 января 2019

Как и ответы выше, я могу повторить, что это во многом зависит от того, что вы проверяете.

В нашем коде было несколько мест, где мы хотели убедиться, что ошибки программиста не могут привести к передаче случайных байтов в качестве закрытых ключей AES или EC и т. Д.

Конкретный характер ошибок, о которых я беспокоился, был больше о 1. шаблонах последовательности байтов и 2. общих значениях bigint, не распределенных случайным образом. Вы можете увидеть список вещей, которые нас беспокоили в модульных тестах.

Не желая иметь дело с установкой numpy везде и проводя множество очень дорогих тестов, я пишу дешевый набор базовых тестов, которые исправили конкретные проблемы, которые мы искали в коде:

В любом случае, вы могли бы сделать то же самое. Используйте модифицированную версию кода adhoc ниже и генерируйте статистику того, что вы считаете хорошим источником случайности. Тогда сравните с вашим сомнительным источником.

https://github.com/earonesty/dotfiles/blob/master/randbytestest.py

Резюме:

  • установить пакет runstats
  • вычисляет статистику по таким вещам, как регрессия для смежных значений, каждого n-го значения, наборов значений, интерпретируемых как отдельные значения
  • вычислить и сохранить статистику для 10 тыс. Сэмплов из urandom
    • randbytestest.py -b -l 1024 -i 10000
    • randbytestest.py -b -l 32 -i 10000
    • randbytestest.py -b -l 16 -i 10000
  • сравнить эти статистические данные с сомнительными значениями с помощью p-val запроса о неверности

Это определенно не строго. Но он также обнаруживает и предотвращает все проблемы, которые нас беспокоили.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...