如何在 Bash 中生成随机数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1194882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to generate random number in Bash?
提问by woakas
How to generate a random number within a range in Bash?
如何在 Bash 中生成一个范围内的随机数?
回答by Nelson
Use $RANDOM
. It's often useful in combination with simple shell arithmetic. For instance, to generate a random number between 1 and 10 (inclusive):
使用$RANDOM
. 它通常与简单的 shell 算法结合使用。例如,要生成 1 到 10(含)之间的随机数:
$ echo $((1 + RANDOM % 10))
3
The actual generator is in variables.c
, the function brand()
. Older versionswere a simple linear generator. Version 4.0 of bash
uses a generator with a citationto a 1985 paper, which presumably means it's a decent source of pseudorandom numbers. I wouldn't use it for a simulation (and certainly not for crypto), but it's probably adequate for basic scripting tasks.
实际的生成器在variables.c
函数中brand()
。旧版本是一个简单的线性发生器。4.0 版bash
使用了一个引用了 1985 年论文的生成器,这大概意味着它是一个不错的伪随机数来源。我不会将它用于模拟(当然也不会用于加密),但它可能足以用于基本的脚本任务。
If you're doing something that requires serious random numbers you can use /dev/random
or /dev/urandom
if they're available:
如果您正在做一些需要严重随机数的事情,您可以使用/dev/random
或/dev/urandom
如果它们可用:
$ dd if=/dev/urandom count=4 bs=1 | od -t d
回答by Andrew Hare
回答by knipwim
You can also use shuf(available in coreutils).
您还可以使用shuf(在 coreutils 中可用)。
shuf -i 1-100000 -n 1
回答by Barun
Try this from your shell:
从你的 shell 试试这个:
$ od -A n -t d -N 1 /dev/urandom
Here, -t d
specifies that the output format should be signed decimal; -N 1
says to read one byte from /dev/urandom
.
此处,-t d
指定输出格式应为有符号十进制;-N 1
说从/dev/urandom
.
回答by ghostdog74
you can also get random number from awk
您还可以从 awk 获取随机数
awk 'BEGIN {
# seed
srand()
for (i=1;i<=1000;i++){
print int(1 + rand() * 100)
}
}'
回答by Antoine Claval
There is $RANDOM. I don't know exactly how it works. But it works. For testing, you can do :
有 $RANDOM。我不知道它是如何工作的。但它有效。对于测试,您可以执行以下操作:
echo $RANDOM
回答by fraff
I like this trick:
我喜欢这个技巧:
echo ${RANDOM:0:1} # random number between 1 and 9
echo ${RANDOM:0:2} # random number between 1 and 99
...
...
回答by David Newcomb
Random number between 0 and 9 inclusive.
0 到 9 之间的随机数。
echo $((RANDOM%10))
回答by Janusz
If you are using a linux system you can get a random number out of /dev/random or/dev/urandom. Be carefull /dev/random will block if there are not enough random numbers available. If you need speed over randomness use /dev/urandom.
如果您使用的是 linux 系统,您可以从/dev/random 或/dev/urandom 中获得一个随机数。如果没有足够的可用随机数,请小心 /dev/random 会阻塞。如果您需要速度超过随机性,请使用 /dev/urandom。
These "files" will be filled with random numbers generated by the operating system. It depends on the implementation of /dev/random on your system if you get true or pseudo random numbers. True random numbers are generated with help form noise gathered from device drivers like mouse, hard drive, network.
这些“文件”将填充操作系统生成的随机数。如果您获得真随机数或伪随机数,这取决于系统上 /dev/random 的实现。真正的随机数是在从鼠标、硬盘驱动器、网络等设备驱动程序收集的帮助形式噪声的帮助下生成的。
You can get random numbers from the file with dd
您可以使用dd从文件中获取随机数
回答by philcolbourn
I have taken a few of these ideas and made a function that should perform quickly if lots of random numbers are required.
我已经采用了其中的一些想法,并制作了一个函数,如果需要大量随机数,它应该可以快速执行。
calling od
is expensive if you need lots of random numbers. Instead I call it once and store 1024 random numbers from /dev/urandom. When rand
is called, the last random number is returned and scaled. It is then removed from cache. When cache is empty, another 1024 random numbers is read.
od
如果您需要大量随机数,则通话费用昂贵。相反,我调用它一次并存储来自 /dev/urandom 的 1024 个随机数。当rand
被调用时,最后一个随机数返回和缩放。然后从缓存中删除。当缓存为空时,再读取 1024 个随机数。
Example:
例子:
rand 10; echo $RET
Returns a random number in RET between 0 and 9 inclusive.
返回 RET 中 0 到 9 之间的随机数。
declare -ia RANDCACHE
declare -i RET RAWRAND=$(( (1<<32)-1 ))
function rand(){ # pick a random number from 0 to N-1. Max N is 2^32
local -i N=
[[ ${#RANDCACHE[*]} -eq 0 ]] && { RANDCACHE=( $(od -An -tu4 -N1024 /dev/urandom) ); } # refill cache
RET=$(( (RANDCACHE[-1]*N+1)/RAWRAND )) # pull last random number and scale
unset RANDCACHE[${#RANDCACHE[*]}-1] # pop read random number
};
# test by generating a lot of random numbers, then effectively place them in bins and count how many are in each bin.
declare -i c; declare -ia BIN
for (( c=0; c<100000; c++ )); do
rand 10
BIN[RET]+=1 # add to bin to check distribution
done
for (( c=0; c<10; c++ )); do
printf "%d %d\n" $c ${BIN[c]}
done
UPDATE: That does not work so well for all N. It also wastes random bits if used with small N. Noting that (in this case) a 32 bit random number has enough entropy for 9 random numbers between 0 and 9 (10*9=1,000,000,000 <= 2*32) we can extract multiple random numbers from each 32 random source value.
更新:这对所有 N 都不是很好。如果与小 N 一起使用,它也会浪费随机位。注意(在这种情况下)32 位随机数具有足够的熵,可用于 0 和 9 之间的 9 个随机数(10 * 9 =1,000,000,000 <= 2*32) 我们可以从每 32 个随机源值中提取多个随机数。
#!/bin/bash
declare -ia RCACHE
declare -i RET # return value
declare -i ENT=2 # keep track of unused entropy as 2^(entropy)
declare -i RND=RANDOM%ENT # a store for unused entropy - start with 1 bit
declare -i BYTES=4 # size of unsigned random bytes returned by od
declare -i BITS=8*BYTES # size of random data returned by od in bits
declare -i CACHE=16 # number of random numbers to cache
declare -i MAX=2**BITS # quantum of entropy per cached random number
declare -i c
function rand(){ # pick a random number from 0 to 2^BITS-1
[[ ${#RCACHE[*]} -eq 0 ]] && { RCACHE=( $(od -An -tu$BYTES -N$CACHE /dev/urandom) ); } # refill cache - could use /dev/random if CACHE is small
RET=${RCACHE[-1]} # pull last random number and scale
unset RCACHE[${#RCACHE[*]}-1] # pop read random number
};
function randBetween(){
local -i N=
[[ ENT -lt N ]] && { # not enough entropy to supply ln(N)/ln(2) bits
rand; RND=RET # get more random bits
ENT=MAX # reset entropy
}
RET=RND%N # random number to return
RND=RND/N # remaining randomness
ENT=ENT/N # remaining entropy
};
declare -ia BIN
for (( c=0; c<100000; c++ )); do
randBetween 10
BIN[RET]+=1
done
for c in ${BIN[*]}; do
echo $c
done