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


12

コマンドラインから/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. 厄介なことに、hexdump64ビット整数(wtf ???)はサポートされていません。
  3. 関数のインターフェイスは機能する必要があります(たとえば、それら-n5も受け入れる必要があります-n 5)が、私のかわいそうなシェルプログラミングスキルを考えると、これは私がすばやくまとめることができる最高のものでした。(コメント/改善はいつものように歓迎します。)

この演習で得た大きな驚きは、シェルで最も基本的な数値をプログラムするのがどれほど難しいかを発見することでした(たとえば、16進数の浮動小数点数を読み取る、または最大のネイティブ浮動小数点数を取得する)...


_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 2016年

私の知る限り、/ dev / randomはそれ自体は乱数を生成しませんが、疑似乱数を与える数学関数にノイズを追加して、予測可能性を低下させます。randomlib.sourceforge.net
Rui F Ribeiro


暗号品質のランダム性が必要ですか、それとも、たとえば、十分な時間に基づいてシードするのですか?
Gilles「SO-邪悪なことをやめなさい」

@ギレス:私の質問の動機は、ランダム性よりもシェルとUnixツールについて知ることでした。バイナリデータのストリームを文字列表現に変換するために存在する基本的なUnixツールを知りたかっただけです。
kjo 2016年

回答:


21

あなたは使用することができます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

man od詳細についてはod



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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.