Объяснение 3 мин чтения

Как работают генераторы случайных чисел: PRNG, CSPRNG и настоящая случайность

Компьютеры детерминированы, так откуда берутся непредсказуемые числа? Объясняем затравки, алгоритмы, энтропию и случайность в браузере.

Случайные числа нужны для розыгрышей, игр, симуляций, паролей и шифрования. Но большинство «случайных» чисел на самом деле не случайны: они получаются из детерминированного процесса, который лишь выглядит непредсказуемым.

Коротко

  • PRNG превращает затравку в длинную повторяемую последовательность.
  • CSPRNG спроектирован так, чтобы прошлые значения не позволяли практически предсказать будущие.
  • Настоящая случайность приходит из физических источников энтропии, а не из одного алгоритма.
  • В браузере есть CSPRNG — crypto.getRandomValues(); именно он подходит для честных розыгрышей.
  • Важен не только источник, но и преобразование значений в диапазон: наивный остаток от деления может давать смещение.

Почему случайность — это сложно

Реклама
Место для рекламы

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

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

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

Что делает PRNG

Генератор псевдослучайных чисел хранит внутреннее состояние. При каждом запросе он преобразует состояние и возвращает часть результата. Преобразование обычно быстрое и детерминированное: одинаковое начальное состояние даёт одинаковую последовательность.

Рано или поздно большинство PRNG повторяют своё состояние. Количество значений до повторения называется периодом. Длинный период полезен, но сам по себе не гарантирует безопасность. Если злоумышленник увидит достаточно выходных данных, он может восстановить состояние и предсказать будущие значения.

PRNG против CSPRNG

Обычный PRNG оптимизирован для скорости и статистического качества. CSPRNG — криптографически стойкий генератор — разработан так, чтобы предсказание было практически невозможным. Он использует криптографические примитивы и скрывает связь между прошлыми и будущими значениями.

Math.random() в JavaScript не подходит для задач, где важна безопасность. Это удобная и быстрая функция, но движки не обещают криптографического качества. Для таких задач браузеры предоставляют crypto.getRandomValues(): он заполняет типизированный массив случайными байтами из криптографического источника платформы.

Для паролей, токенов, призовых розыгрышей и всего, что злоумышленник может захотеть предсказать, используйте CSPRNG. Для декоративной анимации или грубой симуляции обычного PRNG часто достаточно.

Откуда берётся настоящая случайность

Алгоритм не создаёт информацию из ничего. Настоящая случайность приходит из физических процессов: радиоактивного распада, теплового шума, точного времени пользовательских действий. Операционные системы собирают эти сигналы в пул энтропии и используют их для затравки криптографических генераторов.

Современные ОС и браузеры постоянно пополняют энтропию. Вам не нужно специально двигать мышь, чтобы сделать розыгрыш честным, но системе нужен здоровый источник энтропии при загрузке и после долгого простоя. Поэтому криптографические генераторы проектируются тщательно, а не «на коленке».

Как работают генераторы на этом сайте

Инструменты используют crypto.getRandomValues() прямо в вашем браузере. Результаты не отправляются на сервер.

Для целочисленных диапазонов браузер выдаёт 32-битное беззнаковое значение. Наивный способ взять остаток от деления может слегка смещать распределение, если размер диапазона не делит всё 32-битное пространство нацело. Поэтому используется rejection sampling: значения вне равномерной области отбрасываются и запрашиваются заново. В итоге каждое число диапазона имеет одинаковую вероятность.

Для перемешивания применяется алгоритм Фишера–Йетса с безопасными случайными индексами. В отличие от сортировки со случайным компаратором, он даёт каждую перестановку с одинаковой вероятностью.

Какой случайности достаточно для вашей задачи

Обычная псевдослучайность подходит для анимаций, игровой графики и грубых симуляций, где предсказуемость ничего не стоит. CSPRNG нужен для:

  • паролей и кодов восстановления;
  • розыгрышей с реальным призом;
  • распределения людей по командам;
  • токенов, идентификаторов сессий и других задач безопасности;
  • любого розыгрыша, честность которого придётся доказывать публично.

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

Как проверить честность

Простая проверка — сделать много бросков и посмотреть распределение. У шестигранного кубика каждая грань должна выпадать примерно в одной шестой случаев. На коротких сериях возможны отклонения и серии подряд — это нормально. Важно, чтобы процесс был несмещённым на длинной дистанции и чтобы его можно было документировать.

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

Итог

Случайность — это цепочка инженерных решений: сбор энтропии, алгоритм, равномерное преобразование в диапазон и прозрачное использование. Хороший генератор не обязан быть магическим. Ему нужно быть непредсказуемым там, где это важно, документированным там, где его применяют, и честным насчёт своих ограничений.

Попробовать инструмент

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

Целые числа в любом диапазоне.

Открыть генератор
Автор: редакция

Независимые руководства и бесплатные браузерные инструменты для честного и прозрачного случайного выбора.

О сайте