少しググってみたところ、シェルコマンドを使用して、特定の範囲(最小値と最大値の間)に含まれるランダムな10進整数を生成する簡単な方法が見つかりませんでした。
/dev/random
、/dev/urandom
および$RANDOM
、しかしこれらのどれも私が必要とすることを行うことができません。
別の便利なコマンド、または以前のデータを使用する方法はありますか?
POSIXツールチェストでは、awk
を使用できます。
awk -v min=5 -v max=10 'BEGIN{srand(); print int(min+Rand()*(max-min+1))}'
実行notたとえば、ほとんどのawk
実装と同様に、それをソースとして使用してパスワードまたは秘密データを生成します。この数は、コマンドが実行された時間に基づいて簡単に推測できます。
多くのawk
実装では、同じコマンドを同じ秒内に2回実行すると、通常同じ出力が得られます。
GNU coreutilsからshuf
を試すことができます:
shuf -i 1-100 -n 1
BSDおよびOSXでは、jotを使用して、min
からmax
までの1つのランダムな(-r
)番号を返すことができます。
$ 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
5から10(両方を含む)のランダムな整数変数を生成するには、次を使用します。
echo $(( RANDOM % (10 - 5 + 1 ) + 5 ))
%
はモジュロ演算子として機能します。
確率変数$RANDOM
を特定の範囲に変換するより良い方法があるでしょう。これを暗号アプリケーションに使用しないでください。または、シミュレーションのように、実際の等分布確率変数が必要な場合は使用しないでください。
多分UUID
(Linuxの場合)を使用して乱数を取得できます
$ cat /proc/sys/kernel/random/uuid
cdd52826-327d-4355-9737-895f58ad11b4
70
と100
の間の乱数を取得するには
POSIXLY_CORRECT=1 awk -F - '{print(("0x"$1) % 30 + 70)}
' /proc/sys/kernel/random/uuid
# echo $(( $RANDOM % 256 ))
は、現代の* sh方言で0〜255の「ランダムな」数値を生成します。
cat /dev/urandom | tr -dc 'a-fA-F0-9' | fold -w 8 | head -n 1
これにより、8桁の16進数が生成されます。
完全に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の乱数を提供します。
分布は良好です:
for((i = 1; i <= 100000; i ++))do echo $((RANDOM%(20-10 + 1)+ 10));完了|ソート-n | uniq -c
カウント値
9183 10
9109 11
8915 12
9037 13
9100 14
9138 15
9125 16
9261 17
9088 18
8996 19
9048 20
ランダムを使用
MAX=999999 #Upper Range
MIN=100000 #Lower Range
DIFF=$((MAX-MIN+1)) #+1 to inlcude upper limit
R=$(($(($RANDOM%$DIFF))+MIN))
SHUFを使用
MIN=1000
MAX=9999
COUNT=1 #count of Random Numbers to be generated
shuf -i $MIN-$MAX -n $COUNT
shuf -i 1000-9999 -n 1
/ dev/randomを使用
od -An -N2 -i /dev/random #Generates a 2 byte Number, -N2=Generates 2 Random Number btween range 0-65535