Генерация случайных чисел в терминале Bash

Быстрые ссылки
- Random Numbers At The Terminal
О чём эта статья
В статье разъясняется, почему $RANDOM не даёт «истинной» случайности, как улучшить начальное зерно в Bash и какие альтернативы использовать для тестирования и для задач, где требуется высокая криптографическая стойкость. В конце — шаблоны и проверочные чеклисты по ролям.
Как работает $RANDOM
В Bash переменная
$RANDOMвозвращает псевдослучайное число на основе внутреннего генератора, который зависит от начального зерна (seed). Если повторно инициализировать генератор одним и тем же значением RANDOM, последовательность чисел будет повторяться.
Пример установки зерна в Bash:
RANDOM=42
echo $RANDOM
echo $RANDOMЭто удобно для воспроизводимых тестов, но плохо для сценариев, где требуется непредсказуемость.
Важно: псевдослучайность означает предсказуемость при известном зерне.
Зачем нужна энтропия
Энтропия — это мера непредсказуемости входных данных, используемых для инициализации генератора. Чем больше энтропии, тем труднее восстановить или предсказать последовательность.
Если вы используете одно и то же зерно, вы фактически «сокращаете» пространство возможных исходов и делаете генератор предсказуемым.
Попытки быстро получить «рандом» с помощью времени
Одна из распространённых уловок — брать текущее время, например наносекунды, и использовать их как seed:
seed=$(date +%N | cut -c4-9)
RANDOM=$seed
echo $RANDOM
Это даёт большую изменчивость по сравнению с базовой секундной меткой, потому что наносекундный счётчик меняется очень быстро. Однако даже это имеет ограничения:
- Диапазон: если взять 6 цифр наносекунд, получается диапазон 0–999999 (1 миллион вариантов). Это сравнительно мало против пространства ключей в криптографии.
- Воспроизводимость: при наличии логов системы или предсказуемого запуска можно восстановить зерно.
На изображении ниже видно, что секунды увеличиваются по порядку — если вы включаете секунды в зерно, энтропия падает.

Практические рекомендации по выбору источника энтропии
- Для тестов и ненадёжных сценариев: можно использовать $RANDOM с генерацией из времени (наносекунды) или комбинировать PID и время.
- Для генерации ключей, токенов и всего, где требуется криптографическая стойкость: используйте системные криптографические источники (/dev/urandom, getrandom(), OpenSSL, hardware RNG).
- При работе в окружениях с низкой энтропией (виртуальные машины, контейнеры) используйте демоны, пополняющие энтропию: haveged, rngd с поддержкой hwrng.
Важно: /dev/random может блокировать процесс, если энтропии недостаточно; /dev/urandom обеспечивает неблокирующий поток и обычно безопасен для большинства задач, кроме редких ситуаций жёстких требований к безопасности.
Конкретные команды и примеры
- Быстрая демонстрация повтора последовательности при фиксированном зерне:
RANDOM=12345
for i in {1..5}; do echo $RANDOM; done
# повторяем тот же seed
RANDOM=12345
for i in {1..5}; do echo $RANDOM; doneВы получите одинаковые строки чисел при каждом запуске с одним и тем же зерном.
- Использование наносекунд как seed:
seed=$(date +%N | cut -c4-9)
RANDOM=$seed
echo "seed=$seed -> $RANDOM"- Гораздо более надёжный способ получить случайные байты из системы:
# Получить 16 случайных байт в hex через OpenSSL
openssl rand -hex 16
# Получить 16 байт из /dev/urandom
head -c 16 /dev/urandom | xxd -p- Комбинация нескольких источников (для повышения сложности seed; не гарантирует криптографическую безопасность):
seed=$(head -c 16 /dev/urandom | xxd -p)$(date +%s%N)$BASHPID
hash=$(echo -n "$seed" | sha256sum | cut -d ' ' -f1)
# берём часть hash как числовой seed
RANDOM=$((0x${hash:0:6} % 32768))
echo $RANDOMПримечание: в последнем примере мы смешиваем /dev/urandom, время и PID, а затем хэшируем. Это повышает сложность, но если вам действительно нужна криптографическая стойкость — используйте готовые крипто-библиотеки.
Альтернативы и инструменты
- /dev/urandom — неблокирующий системный генератор; подходит для большинства задач, включая HTTPS-сессии и токены.
- /dev/random — блокирует, пока не будет достаточно энтропии; полезен, когда требуется наибольшая возможная непредсказуемость и вы готовы ждать.
- OpenSSL rand — удобно и быстро:
openssl rand -hex 32. - haveged — демонизированный генератор на основе поведения процессора; полезен в VMs.
- rng-tools / rngd — для использования аппаратного hwrng (если он есть) и подпитки ядра Linux.
- Аппаратные HWRNG — USB-токены и встроенные чипы в серверах; дают истинно случайные биты, если устройство сертифицировано.
Когда подход с time-based seed не работает
- Если атакующий может наблюдать или контролировать время запуска программы, он может сузить пространство возможных зерен.
- Для криптозадач важно различать «достаточно случайно для тестов» и «достаточно случайно для ключей» — временные зерна обычно не подходят для ключей.
Мини‑методология выбора генератора
- Определите требование к безопасности (тест, сессия, ключ).
- Если это тест или случайное поведение в приложении — достаточно $RANDOM + время или /dev/urandom.
- Если нужны криптографические свойства — используйте системный крипто-источник (/dev/urandom, getrandom(), OpenSSL) или аппаратный RNG.
- В окружениях с низкой энтропией внедрите haveged или rngd.
- Проводите ревью и тесты на повторяемость и предсказуемость.
Контроль качества и тесты приёмки
Критерии приёмки:
- Для тестовой автоматизации: возможность повторяемости при явном задании seed; при случайном запуске — высокая дисперсия результатов.
- Для производственных токенов и ключей: использован /dev/urandom или эквивалентный крипто-источник; нет использования предсказуемых временных данных как единственного источника.
Тесты:
- Повторяемость: установка известного seed даёт повторяемую последовательность.
- Непредсказуемость: при случайной инициализации последовательности не повторяются между независимыми запусками в обозримом числе итераций.
- Эмпирические тесты: простые статистические проверки (распределение, автокорреляция) для обнаружения очевидных дефектов.
Чек-листы по ролям
Разработчик:
- Не полагаться на $RANDOM для криптоключей.
- Использовать /dev/urandom или библиотечные функции для генерации токенов.
Оператор / DevOps:
- Проверять наличие и работу демонов haveged / rngd в VMs.
- Подключать hwrng в серверах при наличии.
Инженер безопасности:
- Аудит использования генераторов в кодовой базе.
- Рекомендации по шифрованию ключей и хранению.
Краткая справка по терминологии
- Энтропия: мера непредсказуемости данных.
- Псевдослучайный генератор: детерминированный алгоритм, воспроизводимый при одном и том же seed.
- /dev/urandom: неблокирующий системный источник случайных байт.
- /dev/random: блокирующий источник, ждёт накопления энтропии.
Сравнение подходов
- $RANDOM (Bash): прост, воспроизводим, низкая энтропия для криптографии.
- time-based seed (date +%N): лучше, но ограничено диапазоном и предсказуемо в некоторых сценариях.
- /dev/urandom или OpenSSL: надёжно для большинства задач, неблокирующе.
- HWRNG: при наличии — лучший вариант для криптографии.
Риски и смягчение
Риск: использование предсказуемого зерна для генерации ключей. Смягчение: применять системные крипто-источники или аппаратные RNG.
Риск: низкая энтропия в контейнерах/VM. Смягчение: запускать haveged или использовать rngd с доступом к hwrng.
Важно: никогда не храните приватные ключи в виде сгенерированных значений в логе или в открытом виде.
Короткая инструкция для объявления изменений (announcement, 100–200 слов)
Выпущено: обновлённые рекомендации по генерации случайных чисел в Bash. Для тестовой воспроизводимости используйте явные seeds; для производственных случаев и ключей — применяйте системные криптографические источники (/dev/urandom, OpenSSL) или аппаратные генераторы энтропии. В окружениях с низкой энтропией рекомендуется запускать haveged или rngd. Избегайте использования только временных меток (секунды/наносекунды) как единственного источника случайности для чувствительных данных.
Итог
$RANDOM удобен и прост, но детерминированен при фиксированном seed. Для большинства тестовых и утилитарных задач комбинация времени и /dev/urandom будет достаточной. Для криптографических задач пользуйтесь проверенными системными или аппаратными источниками энтропии и строго следуйте политикам безопасности.