🧠 COMPUTER SCIENCE

Почему случайные числа в компьютере на самом деле не случайны

Компьютер — машина абсолютной предсказуемости: одни и те же входные данные всегда дают один и тот же результат. Откуда же тогда берётся random()? Спойлер: это умная подделка, и иногда подделка опасная.

Детерминированная машина в принципе не может выдать настоящую случайность — она может лишь блестяще её имитировать.
То, что вы получаете из обычного random(), — это псевдослучайность: длинная, заранее определённая последовательность, которая лишь притворяется хаосом.

Парадокс в самой основе

Компьютер устроен так, чтобы быть предсказуемым: одна и та же программа на одних и тех же данных даёт идентичный результат — иначе на него нельзя было бы положиться. Но настоящая случайность по определению непредсказуема. Получается противоречие: как детерминированное устройство выдаёт «случай»? Ответ — никак. Оно его подделывает.

Как работает генератор-фокусник

Большинство «случайных» чисел выдаёт псевдослучайный генератор (PRNG). Это формула, которая из текущего числа считает следующее. Вот игрушечный пример — линейный конгруэнтный метод:

seed = 42
def rand():
    global seed
    seed = (1103515245 * seed + 12345) % (2**31)
    return seed

for _ in range(5):
    print(rand())

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

Магическое слово seed

Стартовое число называется seed (зерно). И вот ключевой момент: один и тот же seed всегда порождает одну и ту же «случайную» последовательность. Именно поэтому в играх существуют сиды миров — введёте тот же сид в Minecraft, получите тот же мир. Это не баг, это суть PRNG.

Чтобы числа казались разными при каждом запуске, программы берут seed из чего-то меняющегося — например, из текущего времени в миллисекундах. Но если злоумышленник угадает seed, он предскажет всю последовательность вперёд и назад.

Когда подделка становится опасной

Для перемешивания плейлиста псевдослучайности достаточно. Но в безопасности она убийственна. Реальные истории:

  • Онлайн-казино, где игроки вычислили seed PRNG и предсказывали карты.
  • Криптокошельки, сгенерировавшие ключи на слабом генераторе, — их приватные ключи восстановили перебором seed и увели деньги.
  • Уязвимость в Debian (2008): из-за ошибки seed брался лишь из крошечного диапазона, и тысячи SSH-ключей оказались предсказуемы.

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

Где взять настоящую случайность

Раз арифметика не даёт истинного хаоса, его берут из физического мира — из энтропии:

ТаймингиМикрозадержки между нажатиями клавиш, движениями мыши, приходом пакетов.
Шум железаТепловой шум транзисторов, джиттер тактовых генераторов.
ФизикаРадиоактивный распад, квантовые эффекты — принципиально непредсказуемы.

Операционные системы собирают эту энтропию в общий «пул» и выдают через специальный интерфейс. В Python для безопасности нужен не random, а модуль secrets; в вебе — crypto.getRandomValues, а не Math.random().

Вывод

Запомните разницу: для игр, симуляций и перемешивания — обычный PRNG отлично подходит, он быстрый и воспроизводимый. Для всего, что связано с безопасностью, — только криптостойкий источник с настоящей энтропией. Компьютер сам по себе случайности не создаёт; он либо честно имитирует её формулой, либо подсматривает хаос у реального мира. Перепутать эти два инструмента — классическая и дорогая ошибка.

#PRNG#генераторы#криптография#случайные числа#энтропия