Гид по технологиям

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

6 min read Командная строка Обновлено 21 Nov 2025
Генерация случайных чисел в терминале Bash
Генерация случайных чисел в терминале 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 обеспечивает неблокирующий поток и обычно безопасен для большинства задач, кроме редких ситуаций жёстких требований к безопасности.

Конкретные команды и примеры

  1. Быстрая демонстрация повтора последовательности при фиксированном зерне:
RANDOM=12345
for i in {1..5}; do echo $RANDOM; done

# повторяем тот же seed
RANDOM=12345
for i in {1..5}; do echo $RANDOM; done

Вы получите одинаковые строки чисел при каждом запуске с одним и тем же зерном.

  1. Использование наносекунд как seed:
seed=$(date +%N | cut -c4-9)
RANDOM=$seed
echo "seed=$seed -> $RANDOM"
  1. Гораздо более надёжный способ получить случайные байты из системы:
# Получить 16 случайных байт в hex через OpenSSL
openssl rand -hex 16

# Получить 16 байт из /dev/urandom
head -c 16 /dev/urandom | xxd -p
  1. Комбинация нескольких источников (для повышения сложности 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 не работает

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

Мини‑методология выбора генератора

  1. Определите требование к безопасности (тест, сессия, ключ).
  2. Если это тест или случайное поведение в приложении — достаточно $RANDOM + время или /dev/urandom.
  3. Если нужны криптографические свойства — используйте системный крипто-источник (/dev/urandom, getrandom(), OpenSSL) или аппаратный RNG.
  4. В окружениях с низкой энтропией внедрите haveged или rngd.
  5. Проводите ревью и тесты на повторяемость и предсказуемость.

Контроль качества и тесты приёмки

Критерии приёмки:

  • Для тестовой автоматизации: возможность повторяемости при явном задании 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 будет достаточной. Для криптографических задач пользуйтесь проверенными системными или аппаратными источниками энтропии и строго следуйте политикам безопасности.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство