如何在Bash中生成一个范围内的随机数?
当前回答
从/dev/random或/dev/urandom字符特殊文件读取是可行的方法。
这些设备在读取和设计时返回真正的随机数 帮助应用软件选择用于加密的安全密钥。这样的 随机数是从熵池中提取的 通过各种随机事件。{LDD3,乔纳森·科贝,亚历山德罗 Rubini和Greg Kroah-Hartman]
这两个文件是内核随机化的接口
void get_random_bytes_arch(void* buf, int nbytes)
它从硬件中抽取真正随机的字节,如果这样的功能是由硬件实现的(通常是),或者它从熵池中抽取(包括事件之间的时间,如鼠标和键盘中断,以及注册在SA_SAMPLE_RANDOM中的其他中断)。
dd if=/dev/urandom count=4 bs=1 | od -t d
这是可行的,但将不需要的输出从dd写入到stdout。下面的命令给出了我需要的整数。我甚至可以得到指定的随机位数,因为我需要调整位掩码给算术展开:
me@mymachine:~/$ x=$(head -c 1 /dev/urandom > tmp && hexdump
-d tmp | head -n 1 | cut -c13-15) && echo $(( 10#$x & 127 ))
其他回答
一个bash函数,使用perl生成n位的随机数。指定数字数或n个0的模板。
rand() {
perl -E '$ARGV[0]||=""; $ARGV[0]=int($ARGV[0])||length($ARGV[0]); say join "", int(rand(9)+1)*($ARGV[0]?1:0), map { int(rand(10)) } (0..($ARGV[0]||0)-2)' $1
}
用法:
$ rand 3
381
$ rand 000
728
调用rand n的演示,n在0到15之间:
$ for n in {0..15}; do printf "%02d: %s\n" $n $(rand $n); done
00: 0
01: 3
02: 98
03: 139
04: 1712
05: 49296
06: 426697
07: 2431421
08: 82727795
09: 445682186
10: 6368501779
11: 51029574113
12: 602518591108
13: 5839716875073
14: 87572173490132
15: 546889624135868
演示调用rand n,对于n,一个长度在0到15之间的0模板
$ for n in {0..15}; do printf "%15s :%02d: %s\n" $(printf "%0${n}d" 0) $n $(rand $(printf "%0${n}d" 0)); done
0 :00: 0
0 :01: 0
00 :02: 70
000 :03: 201
0000 :04: 9751
00000 :05: 62237
000000 :06: 262860
0000000 :07: 1365194
00000000 :08: 83953419
000000000 :09: 838521776
0000000000 :10: 2355011586
00000000000 :11: 95040136057
000000000000 :12: 511889225898
0000000000000 :13: 7441263049018
00000000000000 :14: 11895209107156
000000000000000 :15: 863219624761093
从/dev/random或/dev/urandom字符特殊文件读取是可行的方法。
这些设备在读取和设计时返回真正的随机数 帮助应用软件选择用于加密的安全密钥。这样的 随机数是从熵池中提取的 通过各种随机事件。{LDD3,乔纳森·科贝,亚历山德罗 Rubini和Greg Kroah-Hartman]
这两个文件是内核随机化的接口
void get_random_bytes_arch(void* buf, int nbytes)
它从硬件中抽取真正随机的字节,如果这样的功能是由硬件实现的(通常是),或者它从熵池中抽取(包括事件之间的时间,如鼠标和键盘中断,以及注册在SA_SAMPLE_RANDOM中的其他中断)。
dd if=/dev/urandom count=4 bs=1 | od -t d
这是可行的,但将不需要的输出从dd写入到stdout。下面的命令给出了我需要的整数。我甚至可以得到指定的随机位数,因为我需要调整位掩码给算术展开:
me@mymachine:~/$ x=$(head -c 1 /dev/urandom > tmp && hexdump
-d tmp | head -n 1 | cut -c13-15) && echo $(( 10#$x & 127 ))
使用随机的美元。它通常与简单的shell算法结合使用很有用。例如,要生成1到10(包括)之间的随机数:
$ echo $((1 + $RANDOM % 10))
3
实际的生成器在variables.c中,即函数brand()。旧版本是一个简单的线性生成器。bash 4.0版本使用了一个引用1985年论文的生成器,这可能意味着它是一个不错的伪随机数来源。我不会将它用于模拟(当然也不会用于加密),但它可能足以用于基本的脚本任务。
如果你在做一些需要大量随机数的事情,你可以使用/dev/random或/dev/urandom(如果它们可用的话):
$ dd if=/dev/urandom count=4 bs=1 | od -t d
生成随机的3位数字
这对于创建示例数据非常有用。示例:将所有测试数据放在名为“test-create-volume-123”的目录中,然后在测试完成后,删除整个目录。通过生成恰好三个数字,就不会有奇怪的排序问题。
printf '%02d\n' $((1 + RANDOM % 100))
这是按比例缩小的,例如到一个数字:
printf '%01d\n' $((1 + RANDOM % 10))
它可以放大,但只能放大到四位数。原因见上文:)
我就此写了几篇文章。
https://linuxconfig.org/generating-random-numbers-in-bash-with-examples https://linuxconfig.org/random-entropy-in-bash https://www.cloudsavvyit.com/7572/how-to-generate-better-random-numbers-at-the-bash-command-line/
$ RANDOM=$(date +%s%N | cut -b10-19)
$ echo $(( $RANDOM % 113 + 13 ))
上述将给出一个介于13到125(113-1+13)之间的数字,具有合理的随机熵。