少しグーグルで調べた後、シェルコマンドを使用して特定の範囲(最小と最大の間)に含まれるランダムな10進整数を生成する簡単な方法を見つけることができませんでした。
/dev/random
、/dev/urandom
およびについて読みました$RANDOM
が、これらはどれも必要なことを実行できません。
別の便利なコマンド、または以前のデータを使用する方法はありますか?
少しグーグルで調べた後、シェルコマンドを使用して特定の範囲(最小と最大の間)に含まれるランダムな10進整数を生成する簡単な方法を見つけることができませんでした。
/dev/random
、/dev/urandom
およびについて読みました$RANDOM
が、これらはどれも必要なことを実行できません。
別の便利なコマンド、または以前のデータを使用する方法はありますか?
回答:
POSIXツールチェストでは、次を使用できますawk
。
awk -v min=5 -v max=10 'BEGIN{srand(); print int(min+rand()*(max-min+1))}'
これをソースとして使用してパスワードや秘密データを生成しないでください。ほとんどのawk
実装では、コマンドが実行された時間に基づいて数字を簡単に推測できます。
多くのawk
実装では、同じコマンドを同じ秒内に2回実行すると、一般に同じ出力が得られます。
x=$(awk -v min=$min_var -v max=$max_var 'BEGIN{srand(); printf("%.2d", int(min+rand()*(max-min+1)))}')
awk -v min=5 -v max=10 -v seed="$(od -An -N4 -tu4 /dev/urandom)" 'BEGIN{srand(seed+0); print int(min+rand()*(max-min+1))}'
。$RANDOM
代わりに使用することもできますod ... /dev/random
が、シード値は0から32767の比較的小さい範囲にあるため、時間の経過とともに出力に顕著な繰り返しが発生する可能性があります。
BSDやOSX上では使用することができますJOTを単一のランダム(戻るには-r
間隔から)数をmin
するmax
包括的、。
$ min=5
$ max=10
$ jot -r 1 $min $max
残念ながら、ランダムに生成された数値の範囲と分布は、jotが内部的に倍精度浮動小数点演算を使用し、出力形式にprintf(3)を使用するという事実に影響されます。そのため、インターバルのはmin
とmax
それほど頻繁に実証されたように生成されます。
$ jot -r 100000 5 10 | sort -n | uniq -c
9918 5
20176 6
20006 7
20083 8
19879 9
9938 10
OS X 10.11(El Capitan)では、これは修正されたようです:
$ jot -r 100000 5 10 | sort -n | uniq -c
16692 5
16550 6
16856 7
16579 8
16714 9
16609 10
そして...
$ jot -r 1000000 1 10 | sort -n | uniq -c
100430 1
99965 2
99982 3
99796 4
100444 5
99853 6
99835 7
100397 8
99588 9
99710 10
古いバージョンのOS Xの場合、幸いなことにいくつかの回避策があります。1つは、printf(3)整数変換を使用することです。唯一の注意点は、間隔の最大値がになったことmax+1
です。整数のフォーマットを使用することにより、間隔全体に均等に分布します。
$ jot -w %i -r 100000 5 11 | sort -n | uniq -c
16756 5
16571 6
16744 7
16605 8
16683 9
16641 10
最後に、回避策を使用してサイコロの公平なロールを取得するには、次のものがあります。
$ min=5
$ max_plus1=11 # 10 + 1
$ jot -w %i -r 1 $min $max_plus1
血みどろの数学と書式設定の詳細およびその他の例については、jot (1)を参照してください。
この$RANDOM
変数は通常、適切なランダム値を生成するのに適した方法ではありません。の出力/dev/[u]random
も最初に変換する必要があります。
より簡単な方法は、たとえばpythonのような高レベル言語を使用することです:
5〜10(5 <= N <= 10)の間のランダムな整数変数を生成するには、次を使用します。
python -c "import random; print random.randint(5,10)"
暗号化アプリケーションにはこれを使用しないでください。
乱数を取得できます urandom
head -200 /dev/urandom | cksum
出力:
3310670062 52870
上記の数値の一部を取得します。
head -200 /dev/urandom | cksum | cut -f1 -d " "
次に、出力は
3310670062
head -200
(またはそのPOSIX同等物head -n 100
)は、の最初の200 行を返します/dev/urandom
。/dev/urandom
テキストファイルではありません。このコマンドは200バイト(すべて0x0aの1、ASCIIのLF)から無限(0xaバイトが返されない場合)に戻る可能性がありますが、45k〜55kの値が最も可能性が高いです。cksumは32ビットの数値を返すため、から4バイト以上を取得しても意味がありません/dev/urandom
。
5〜10(両方を含む)の間のランダムな整数変数を生成するには、次を使用します。
echo $(( RANDOM % (10 - 5 + 1 ) + 5 ))
%
モジュロ演算子として機能します。
おそらく、ランダム変数$RANDOM
を特定の範囲に変換するより良い方法があります。これを暗号化アプリケーションに使用したり、実際の等分布ランダム変数(シミュレーションなど)が必要な場合は使用しないでください。
完全にbash内にとどまり、$ RANDOM変数を使用するが、不均一な分布を回避するには:
#!/bin/bash
range=10
floor=20
if [ $range -gt 32768 ]; then
echo 'range outside of what $RANDOM can provide.' >&2
exit 1 # exit before entering infinite loop
fi
max_RANDOM=$(( 2**15/$range*$range ))
r=$RANDOM
until [ $r -lt $max_RANDOM ]; do
r=$RANDOM
done
echo $(( r % $range + $floor ))
この例では、20〜29の乱数が提供されます。
$r
[: -lt: unary operator expected
エラーを回避するには、65535または他の高い値に初期化する必要があります。