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

时间:2014-04-05 22:51:30

标签: bash random

例如,

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

可以使用。但它不适用于更大的数字。

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

4 个答案:

答案 0 :(得分:6)

我使用:

shuf -i0-999999999 -n1

虽然无法保证shuf使用/dev/random。使用GNU shuf,如果您真的想要,可以指定--random-source=/dev/random

IIRC,FreeBSD(可能还有Mac OS X)调用此实用程序shuffle,它需要稍微不同的参数(shuffle -n1000000000 -p1)。

如果您确实想直接使用/dev/random,可以使用od -An -N4 -tu4生成一个四字节数字,但请记住使用%1000000000会产生偏差,因为2 < sup> 32 不能被1000000000整除。为了纠正这种情况,在0-999999999范围内生成随机数的特定情况下,如果大于或等于4000000000,则需要拒绝这个四字节随机数。

答案 1 :(得分:1)

<强> Explenation

使用/dev/random执行此操作的关键是考虑产生均匀分布的原因。 /dev/random确实如此,但正在做

 od -An -N2 -i /dev/random

提供2字节输出,在0 ... 2 16 -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位数的随机数,只需执行类似

的操作
#!/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

答案 2 :(得分:0)

你可以使用awk,它几​​乎可以在任何类似UNIX的盒子上使用:

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

答案 3 :(得分:0)

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

来自/dev/random的Cat随机数据,删除除01,... 9以外的所有数据;然后用dd等待9位数。