web-dev-qa-db-ja.com

/ dev / random、/ dev / urandomを使用してランダムデータを生成する

コマンドラインから_/dev/random_(または_/dev/urandom_)を使用する方法を探しています。特に、stdinなどのストリームを使用して、乱数のストリームをstdout(1行に1つの数値)に書き込む方法を教えてください。

マシンのアーキテクチャがネイティブでサポートしているすべての数値型の乱数に興味があります。例えば。 64ビットアーキテクチャの場合、これらには64ビットの符号付き整数と符号なし整数、および64ビット浮動小数点数が含まれます。範囲に関する限り、さまざまな数値タイプの最大範囲で十分です。

Perl、Pythonなどの多目的インタープリターでこれを行う方法を知っていますが、シェルの「より単純な」ツールでこれを行う方法を知りたいです。 (「より単純」とは、「最小限のUnixインストールでも利用できる可能性が高い」という意味です。)

基本的に、この問題により、コマンドラインでバイナリデータを文字列表現に変換する問題が軽減されます。 (たとえば、これは機能しません:printf '%f\n' $(head -c8 /dev/random)。)

シェルにとらわれない答えを探しています。また、_/dev/random_と_/dev/urandom_の違いは、この質問では重要ではありません。結果のセマンティクスが異なる場合でも、1つの手順で機能する手順が他の手順でも機能することを期待しています。


EightBitTonyの回答を適用して、以下に示す関数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_を受け入れる必要があります)。 (いつものように、コメント/改善は歓迎します。)

私がこの演習で得た大きな驚きは、シェルでプログラムすることhardがどのようにmost elementary数値のものであるかを発見することでした(たとえば、16進数の浮動小数点数を読み取る、または最大値を取得する)ネイティブfloat値)...


__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'
}
_
11
kjo

odを使用すると、/dev/randomおよび/dev/urandomから数値を取得できます。

例えば、

2バイトの符号なし10進整数、

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

1バイトの符号付き10進整数、

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

4バイトの符号なし10進整数、

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

odの詳細については、man odをご覧ください。

20
EightBitTony

一部のシェル(bash(1)など)には$RANDOM乱数を与える「変数」。

8
vonbrand

あなたは次のようなことをすることができます:

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
1