如何在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 18:21:06  来源:igfitidea点击:

How to generate random number in Bash?

bashshellrandom

提问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 bashuses 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/randomor /dev/urandomif they're available:

如果您正在做一些需要严重随机数的事情,您可以使用/dev/random/dev/urandom如果它们可用:

$ dd if=/dev/urandom count=4 bs=1 | od -t d

回答by Andrew Hare

Please see $RANDOM:

请参阅$RANDOM

$RANDOMis an internal Bash function (not a constant) that returns a pseudorandom integer in the range 0 - 32767. It should not be used to generate an encryption key.

$RANDOM是一个内部 Bash 函数(不是常数),它返回一个范围为 0 - 32767 的伪随机整数。它不应用于生成加密密钥。

回答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 dspecifies that the output format should be signed decimal; -N 1says 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 odis expensive if you need lots of random numbers. Instead I call it once and store 1024 random numbers from /dev/urandom. When randis 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