web-dev-qa-db-ja.com

特定の範囲の乱数を生成する

少しググってみたところ、シェルコマンドを使用して、特定の範囲(最小値と最大値の間)に含まれるランダムな10進整数を生成する簡単な方法が見つかりませんでした。

/dev/random/dev/urandomおよび$RANDOM、しかしこれらのどれも私が必要とすることを行うことができません。

別の便利なコマンド、または以前のデータを使用する方法はありますか?

94
BowPark

POSIXツールチェストでは、awkを使用できます。

awk -v min=5 -v max=10 'BEGIN{srand(); print int(min+Rand()*(max-min+1))}'

実行notたとえば、ほとんどのawk実装と同様に、それをソースとして使用してパスワードまたは秘密データを生成します。この数は、コマンドが実行された時間に基づいて簡単に推測できます。

多くのawk実装では、同じコマンドを同じ秒内に2回実行すると、通常同じ出力が得られます。

49

GNU coreutilsからshufを試すことができます:

shuf -i 1-100 -n 1
151
cuonglm

書きます

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) を参照してください。

33
Clint Pachl

$RANDOM変数は、通常、適切なランダム値を生成するための良い方法ではありません。 /dev/[u]randomの出力も最初に変換する必要があります。

より簡単な方法は、次のような高レベルの言語を使用することです。 python:

5から10(5 <= N <= 10)のランダムな整数変数を生成するには、次を使用します。

python -c "import random; print random.randint(5,10)"

これを暗号化アプリケーションに使用しないでください。

16
jofel

urandomから乱数を取得できます

head -200 /dev/urandom | cksum

出力:

3310670062 52870

上記の数値の一部を取得します。

head -200 /dev/urandom | cksum | cut -f1 -d " "

次に、出力は

3310670062

14
zangw

5から10(両方を含む)のランダムな整数変数を生成するには、次を使用します。

echo $(( RANDOM % (10 - 5 + 1 ) + 5 ))

%はモジュロ演算子として機能します。

確率変数$RANDOMを特定の範囲に変換するより良い方法があるでしょう。これを暗号アプリケーションに使用しないでください。または、シミュレーションのように、実際の等分布確率変数が必要な場合は使用しないでください。

10
jofel

多分UUID(Linuxの場合)を使用して乱数を取得できます

$ cat /proc/sys/kernel/random/uuid
cdd52826-327d-4355-9737-895f58ad11b4

70100の間の乱数を取得するには

POSIXLY_CORRECT=1 awk -F - '{print(("0x"$1) % 30 + 70)}
   ' /proc/sys/kernel/random/uuid
6
zangw

# echo $(( $RANDOM % 256 ))は、現代の* sh方言で0〜255の「ランダムな」数値を生成します。

6
qrkourier
cat /dev/urandom | tr -dc 'a-fA-F0-9' | fold -w 8 | head -n 1

これにより、8桁の16進数が生成されます。

4
Tom Cooper

完全に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の乱数を提供します。

2
Than Angell

分布は良好です:

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

1
SteveK

ランダムを使用

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
0
Aashutosh