9.3 $RANDOM:生成随机数
任何试图通过确定性方法生成随机数的行为都是在犯罪。
—— 约翰·冯·诺伊曼
$RANDOM 是 Bash 中用来生成 0 至 32767 之间随机整数的一个内置 函数(而非常量)。其不应被用于生成密钥。
样例 9-11. 生成随机数
#!/bin/bash
# $RANDOM 每一次调用都会返回一个随机的不同的整数。
# 随机数的标称范围为 0 - 32767(16位有符号整型)。
MAXCOUNT=10
count=1
echo
echo "$MAXCOUNT random numbers:"
echo "-----------------"
while [ "$count" -le $MAXCOUNT ] # 生成 10 ($MAXCOUNT) 个随机整数。
do
number=$RANDOM
echo $number
let "count += 1" # 增加计数。
done
echo "-----------------"
# 如果你需要一个小于指定上界的随机数,可以使用 'modulo' 操作符。
# 该操作符可以返回除法后的余数。
RANGE=500
echo
number=$RANDOM
let "number %= $RANGE"
# ^^
echo "Random number less than $RANGE --- $number"
echo
# 如果你需要生成的随机数大于一个指定的下界,
#+ 可以增加一步判断,判别并丢弃所有小于下界的数。
FLOOR=200
number=0 # 初始化
while [ "$number" -le $FLOOR ]
do
number=$RANDOM
done
echo "Random number greater than $FLOOR --- $number"
echo
# 现在来看一种可以代替上面循环的更简单的方式,也就是
# let "number = $RANDOM + $FLOOR"
# 该方式可以不使用 while 循环,效率更高。
# 但是,该方法可能会产生一些问题,是什么呢?
# 通过结合上面的两种方法,可以获得一个特定范围内的随机数。
number=0 # 初始化
while [ "$number" -le $FLOOR ]
do
number=$RANDOM
let "number %= $RANGE" # 将 $number 缩小至 $RANGE 的范围内。
done
echo "Random number between $FLOOR and $RANGE --- $number"
echo
# 生成二元选择值,即真(true)或假(false)。
BINARY=2
T=1
number=$RANDOM
let "number %= $BINARY"
# 如果使用 let "number >>= 14" 可以获得更优的随机分布
#+ (除了最低位,其余二进制位都右移)。
if [ "$number" -eq $T ]
then
echo "TRUE"
else
echo "FALSE"
fi
echo
# 扔一个骰子。
SPOTS=6 # 模 6 的余数范围为 0 - 5。
# 然后加 1 就可以得到期望的范围 1 - 6。
# 感谢 Paulo Marcel Coelho Aragao 简化了代码。
die1=0
die2=0
# 如果设置 SPOTS=7 就可以不用加 1 得到值。这是不是一种更好的方法,为什么?
# 为了保证公平,独立的投每一个骰子。
let "die1 = $RANDOM % $SPOTS + 1" # 投第一个骰子。
let "die2 = $RANDOM % $SPOTS + 1" # 投第二个骰子。
# 哪一种运算符有更高的优先级,
#+ 取余(%)还是加法(+)?
let "throw = $die1 + $die2"
echo "Throw of the dice = $throw"
echo
exit 0样例 9-12. 从牌组中随机选牌
Example 9-13. 模拟布朗运动
Jipe 提供了一些生成指定范围内随机数的方法。
Bill Gradwohl 提出了一种改良后的仅适用于正数的公式。
Bill 在这还给出了一个生成指定范围内随机数的通用函数。
样例 9-14. 指定范围随机数
那么 $RANDOM 到底有多随机?最好的测试方法就是写一个脚本跟踪由 $RANDOM 生成的随机数的分布。接下来让我们多投几次由 $RANDOM 做的骰子...
样例 9-15. 用 RANDOM 投骰子
RANDOM 投骰子从上一个样例中我们可以发现,在每次调用 RANDOM 生成器时,最好利用重置生成器种子。在 RANDOM 生成器中使用相同的种子会生成相同序列的随机数。(与 C 语言中的 random() 函数的行为一致)
样例 9-16. 重置 RANDOM 种子
RANDOM 种子注记
Last updated
Was this helpful?