Я ищу способы использования /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должен дать вам только целое число.