如何在Bash中获取0到999999999之间的随机(/dev/random)数字?

4
例如,
echo "$(( ($(od -An -N2 -i /dev/random) )%(1000-0+1) ))"

可以使用。但是对于更大的数字不具备可扩展性。

如何在bash中获取0到999999999之间的随机(/dev/random)数?


1
你能把这三个放在一排吗? - Gabe
1
生成9个1位数字并将它们与10的幂附加在一起,大数定律表明它们具有相同的随机分布,尽管因为/ dev / random不是那么随机,因此它会出错,但它已经损坏了,所以... :D - Benjamin Gruenbaum
1
你能把它们排成一排吗?这样做会得到不同的随机数,而不是一次性完成。 - adrelanos
4个回答

7

我建议使用:

shuf -i0-999999999 -n1

尽管不能保证shuf使用/dev/random。如果您确实想要,可以通过GNU shuf指定--random-source=/dev/random
据我所知,FreeBSD(以及可能是Mac OS X)将此实用程序称为shuffle,并且它需要略微不同的参数(shuffle -n1000000000 -p1)。
如果您真的想直接使用/dev/random,则可以通过使用od -An -N4 -tu4生成一个四字节数字,但请记住,使用%1000000000会产生偏差,因为232不能被1000000000整除。为了纠正这个问题,在生成0-999999999范围内的随机数的特定情况下,如果四字节随机数大于或等于4000000000,则需要拒绝该数字。

真的不在0到999999999之间吗?我已经运行了100次,总是得到8或9位数字的结果。从未出现过像443242这样的较小数字。 - adrelanos
@adrenalos:得到一个七位数的概率是100分之1。因此,进行100次重复并不是一个非常好的测试。 - rici
最小的数字出现的概率要小得多。100次显然不足以得到它们。 - osgx
+1 这应该被接受为答案。当发布我的解释时,我错过了你的解释,本质上做的是相同的事情(尽管这个可能稍微快一点)。 - Reinstate Monica Please

1

解释

使用 /dev/random 的关键在于思考如何产生均匀分布。 /dev/random 可以实现,但是需要注意:

 od -An -N2 -i /dev/random

提供一个2字节的输出,它在0...216-1或0...65535上是均匀的。但显然在0...99999上不是均匀的。
对它取模1000,会将输出更改为0...999,但分布仍不均匀。
解决方案
假设我们有一个伪随机生成器,产生0,1,2,3,4,但我们想要一个产生0,1的生成器。我们只忽略任何输出2,3,4并保留输出0,1,根据定义,这些仍必须是伪随机的。
因此,您可以像这样做。
要获取单个数字,您可以这样做。
while :; do ran=$(echo $(od -An -N1 -i /dev/random)) && [[ $ran -lt 250 ]] && \
echo ${ran: -1} && break; done

由于0...249的最低有效数字的分布是均匀的,因此可以构建一个9位随机数,只需执行以下操作:

然后构建一个9位随机数,只需执行以下操作:

#!/bin/bash

digit() {
  while :; do ran=$(echo $(od -An -N1 -i /dev/random)) && [[ $ran -lt 250 ]] && \
  echo ${ran: -1} && break; done
}

for ((i=0; i<9; i++)) {
  num+=$(digit)
}

echo $num

1
 cat /dev/random | tr -cd 0-9 | dd bs=1 count=9

/dev/random中获取随机数据,删除除01、... 9之外的所有内容;然后使用dd仅等待9个数字。

0

您可以使用 awk,它应该在几乎所有类UNIX系统上都可用:

awk 'BEGIN{print int(rand()*999999999)}'

2
这个是否使用了/dev/random - adrelanos
这并不是因为有一个名为srand()的方法用于种子生成器,这意味着伪随机生成器。strace -eopen awk 'BEGIN{print int(rand()*999999999)}'也没有显示打开/dev/random。但是,您可以从/dev/random/读取一些数据来使用srand()种子伪随机数生成器。虽然这不如直接使用/dev/random好,但仍然可行。 - Michał Kosmulski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接