我正在寻找从命令行使用/dev/random
(或/dev/urandom
)的方法。特别是,我想知道如何使用这样的流stdin
将随机数流写入stdout
(每行一个数字)。
我对机器体系结构本机支持的所有数字类型的随机数感兴趣。例如,对于64位架构,这些将包括64位有符号和无符号整数以及64位浮点数。就范围而言,各种数字类型的最大范围都可以。
我知道如何使用通用解释器(例如Perl,Python等)来完成所有这些操作,但是我想知道如何使用外壳中的“更简单”的工具来执行此操作。(“简单”是指“即使在最小的Unix安装中也更有可能使用”。)
基本上,该问题减少了在命令行上将二进制数据转换为其字符串表示形式的问题。(例如,这不会:)printf '%f\n' $(head -c8 /dev/random)
。
我正在寻找与外壳无关的答案。此外,之间的差别/dev/random
,并/dev/urandom
没有对这个问题很重要。我希望即使对结果的语义可能有所不同,任何适用于一个过程的过程也会适用于另一个过程。
我改编了SevenBitTony的答案以产生toints
如下所示的函数等。
使用示例:
% < /dev/urandom toprobs -n 5
0.237616281778928
0.85578479125532
0.0330049682019756
0.798812391655243
0.138499033902422
备注:
- 我使用
hexdump
而不是od
因为它为我提供了一种更轻松的方式来格式化输出,使其符合我的期望。 - 令人讨厌的是,
hexdump
它不支持64位整数(wtf ???); - 函数的接口需要工作(例如,它们应该接受
-n5
和-n 5
),但是鉴于我可怜的shell编程技能,这是我可以快速组合的最好方法。(一如既往地欢迎评论/改进。)
我从这次练习中得到的最大惊喜是发现在shell上编写最基本的数字内容有多难(例如,读取十六进制浮点数或获取最大本机浮点值)...
_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'
}
据我所知,/ dev / random本身不会生成随机数,但是会给数学函数增加噪音,这些数学函数使伪随机数变得难以预测。您可能想看看randomlib.sourceforge.net
—
Rui F Ribeiro
您是否需要加密质量的随机性,或者例如基于时间的播种是否足够好?
—
吉尔斯(Gillles)“所以-别再作恶了”
@Gilles:我的问题的动机更多是去了解Shell和Unix工具,而不是去发现随机性。我只是想知道存在哪些基本的Unix工具,用于将二进制数据流转换为它们的字符串表示形式。
—
kjo
tr -cs '[:digit:]' '[\n*]' </dev/urandom
应该只给您整数。