Сегодня про RANDOM и револьвер
В бородатые 2000е была такая консольная игруля «Русская рулетка», состояла она из одной строчки:
[ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo "You live"
Для начала давай сделаем её более безопасной:
[ $[ $RANDOM % 6 ] == 0 ] && echo 'You died' || echo 'You live'
Суть такая: Если деление по модулю псевдослучайного числа переменной RANDOM вернёт - 0, значит тебе песда и пистолет выстрелил. Соответственно если > 0, то ты пока еще жив и тебе повезло.
А теперь давай посмотрим на условия, при которых «пистолет выстрелит» сразу.
Число отличное от 0, указанное в качестве переменной RANDOM используется как seed (семя) для генератора псевдослучайных чисел. Если посеять число 2, то при первом обращении к переменной RANDOM получим значение, которое делится на 6 без остатка.
RANDOM=2
[ $[ $RANDOM % 6 ] == 0 ] && echo 'You died' || echo 'You live'
Этот посев даст нужное в разных версиях интерпретатора. Все дело в том, что в версии bash 5.1 были внесены изменения связанные с этим. Короче если у тебя версия баша > 5.0, то можно изменить поведение генератора с помощью переменной BASH_COMPAT.
Так, давай теперь это проверим:
( BASH_COMPAT=51 ; RANDOM=0 ; echo $RANDOM )
Получаем значение: 20814
( BASH_COMPAT=50 ; RANDOM=0 ; echo $RANDOM )
А тут уже другое: 20034
Если мы задаем 0 в переменную RANDOM, тогда семя (seed) инициализируется жестко заданным значением. При котором генерируется требуемое число, то есть делится на 6 без остатка.
RANDOM=0
[ $[ $RANDOM % 6 ] == 0 ] && echo 'You died' || echo 'You live'
Тут пистолет гарантированно выстрелит. Аналогично предыдущему примеру, если начало строки не число:
RANDOM='bashdays'
[ $[ $RANDOM % 6 ] == 0 ] && echo 'You died' || echo 'You live'
Снова получим 100% выстрел.
Как работает генератор:
Начальное значение seed, оболочка получает совершая манипуляции над значениями pid, ppid, uid + текущее время (секунды, микросекунды).
Далее полученное значение пропускается через алгоритм, а результат сохраняется. При следующих обращениях также пропускается через алгоритм.
Потом полученное число усекается. В документации указано максимальное возможное значение 32767.
Такие дела, исследуйте!








Комментарии
Виджет комментариев загружается с серверов Telegram и может использовать cookies. Разрешите внешние сервисы, чтобы открыть обсуждение.