例如,
echo "$(( ($(od -An -N2 -i /dev/random) )%(1000-0+1) ))"
可以使用。但它不适用于更大的数字。
如何在bash中获得0到999999999之间的随机(/ dev / random)数字?
答案 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随机数据,删除除0
,1
,... 9
以外的所有数据;然后用dd等待9位数。