Я ищу способы использования /dev/random
(или /dev/urandom
) из командной строки. В частности, я хотел бы знать, как использовать такой поток, stdin
чтобы записывать потоки случайных чисел stdout
(по одному числу в строке).
Меня интересуют случайные числа для всех числовых типов, которые изначально поддерживает архитектура машины. Например, для 64-битной архитектуры они будут включать 64-битные целые числа со знаком и без знака и 64-битные числа с плавающей запятой. Что касается диапазонов, то подойдут максимальные диапазоны для различных числовых типов.
Я знаю, как сделать все это с помощью универсальных интерпретаторов, таких как Perl, Python и т. Д., Но я хотел бы знать, как это сделать с помощью «более простых» инструментов из оболочки. (Под «проще» я подразумеваю «более вероятно, что он будет доступен даже при очень минимальной установке Unix».)
По сути, проблема сводит проблему преобразования двоичных данных в их строковые представления в командной строке. (Например, это не будет делать:. printf '%f\n' $(head -c8 /dev/random)
)
Я ищу не зависящие от раковины ответы. Также разница между /dev/random
и /dev/urandom
не важна для этого вопроса. Я ожидаю, что любая процедура, которая работает для одного, будет работать для другого, даже если семантика результатов может отличаться.
Я адаптировал ответ EightBitTony для создания функций toints
и т. Д., Показанных ниже.
Пример использования:
% < /dev/urandom toprobs -n 5
0.237616281778928
0.85578479125532
0.0330049682019756
0.798812391655243
0.138499033902422
Примечания:
- Я использую
hexdump
вместо,od
потому что это дало мне более простой способ форматировать вывод, как я хотел; - Досадно,
hexdump
что 64-битные целые числа не поддерживаются (wtf ???); - Интерфейс функций нуждается в работе (например, они должны принимать
-n5
также-n 5
), но, учитывая мои жалкие навыки программирования оболочки, это было лучшее, что я мог собрать быстро. (Комментарии / улучшения приветствуются, как всегда.)
Большое удивление, которое я получил от этого упражнения, заключалось в том, как трудно запрограммировать на оболочке самые элементарные числовые вещи (например, прочитать шестнадцатеричное число с плавающей запятой или получить максимальное значение собственного числа с плавающей запятой) ...
_tonums () {
local FUNCTION_NAME=$1 BYTES=$2 CODE=$3
shift 3
local USAGE="Usage: $FUNCTION_NAME [-n <INTEGER>] [FILE...]"
local -a PREFIX
case $1 in
( -n ) if (( $# > 1 ))
then
PREFIX=( head -c $(( $2 * $BYTES )) )
shift 2
else
echo $USAGE >&2
return 1
fi ;;
( -* ) echo $USAGE >&2
return 1 ;;
( * ) PREFIX=( cat ) ;;
esac
local FORMAT=$( printf '"%%%s\\n"' $CODE )
$PREFIX "$@" | hexdump -ve $FORMAT
}
toints () {
_tonums toints 4 d "$@"
}
touints () {
_tonums touints 4 u "$@"
}
tofloats () {
_tonums tofloats 8 g "$@"
}
toprobs () {
_tonums toprobs 4 u "$@" | perl -lpe '$_/=4294967295'
}
tr -cs '[:digit:]' '[\n*]' </dev/urandom
должен дать вам только целое число.