使用/ dev / random,/ dev / urandom生成随机数据


12

我正在寻找从命令行使用/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

备注:

  1. 我使用hexdump而不是od因为它为我提供了一种更轻松的方式来格式化输出,使其符合我的期望。
  2. 令人讨厌的是,hexdump它不支持64位整数(wtf ???);
  3. 函数的接口需要工作(例如,它们应该接受-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'
}

1
tr -cs '[:digit:]' '[\n*]' </dev/urandom应该只给您整数。
cuonglm

据我所知,/ dev / random本身不会生成随机数,但是会给数学函数增加噪音,这些数学函数使伪随机数变得难以预测。您可能想看看randomlib.sourceforge.net
Rui F Ribeiro


您是否需要加密质量的随机性,或者例如基于时间的播种是否足够好?
吉尔斯(Gillles)“所以-别再作恶了”

@Gilles:我的问题的动机更多是去了解Shell和Unix工具,而不是去发现随机性。我只是想知道存在哪些基本的Unix工具,用于将二进制数据流转换为它们的字符串表示形式。
kjo

Answers:


21

您可以使用od来获取来自/dev/random和的数字/dev/urandom

例如,

2字节无符号十进制整数,

$ od -vAn -N2 -tu2 < /dev/urandom
24352

1字节有符号十进制整数,

$ od -vAn -N1 -td1 < /dev/urandom
-78

4字节无符号十进制整数,

$ od -vAn -N4 -tu4 < /dev/urandom
3394619386

man od有关的更多信息od


8

一些外壳(例如bash(1))具有$RANDOM提供随机数的“变量”。


1

您可以执行以下操作:

perl -le '
  while (q(
    c char,  C unsigned char, s! short, S! unsigned short,
    i! int,  I! unsigned int, l! long,  L! unsigned long,
    f float, d double,) =~ /(\S+) (.*?),/gs) {
    $size = length(pack $1, 0);
    sysread STDIN, $data, $size;
    print "$2($size): " . unpack($1, $data);
  }' < /dev/urandom

在64位系统上,它将为您提供以下信息:

char(1): -98
unsigned char(1): 62
short(2): -12526
unsigned short(2): 399
int(4): 499066219
unsigned int(4): 2312134917
long(8): -4889591208978026255
unsigned long(8): 2080566823379835456
float(4): 55.4727554321289
double(8): 8.6395690272822e-05
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.