环境:
- 德班
- 重击
已知的情况:
RANDOM
通过以下方式给出 15 位范围内的随机数:
echo $RANDOM
SRANDOM
通过以下方式给出 32 位范围内的随机数:
echo $SRANDOM
RANDOM
可以通过以下方式配置为创建 30 位范围内的随机数:
my_rnd=$(((RANDOM<<15|RANDOM)))
echo "$my_rnd"
RANDOM
可以通过以下方式配置为创建 45 位范围内的随机数:
my_rnd=$(((RANDOM<<15|RANDOM)<<15|RANDOM))
echo "$my_rnd"
如何配置RANDOM
以获得与使用时相同的 32 位范围的随机数SRANDOM
?
答案1
my_rnd=$(((RANDOM<<15|RANDOM)))
其作用只是使用RANDOM
两次,每次 15 位,第一个值向左移动 15 位。因此,您会得到一个类似于 的二进制数aaaaaaaaaaaaaaabbbbbbbbbbbbbbb
,其中 a 是代表第一个值的位,b 是代表第二个值的位。
类似地,要获得任意数量的位,您可以使用RANDOM
或SRANDOM
来生成至少那么多位,并与 shift ( <<
) 和或者( |
),然后用和( &
)。例如,对于 32 位,您可以使用以下掩码0xffffffff
:
echo "$(( ((RANDOM<<30) | (RANDOM<<15) | RANDOM) & 0xffffffff ))"
(0xffffffff
是最大的 32 位二进制值,十进制为 4294967295。您也可以用来((1 << 32) - 1)
即时计算它。)
请注意,Bash 的手册似乎没有对 产生的值的不可预测性做出任何承诺RANDOM
,但SRANDOM
它说:
SRANDOM
每次引用该变量时,它都会扩展为 32 位伪随机数。随机数生成器在支持/dev/urandom
或 的系统上不是线性的arc4random
,因此每个返回的数字与其前面的数字没有关系。
这意味着这RANDOM
确实可能是线性同余发生器,也就是说,这不是一个很好的随机生成器。/dev/urandom
并arc4random
使用更好的算法实现,因此如果可用,您应该使用SRANDOM
.
即使SRANDOM
在您的 Bash 版本中不可用,您的系统也可能可用/dev/urandom
。因此,如果您确实需要比RANDOM
提供的更好的随机数,您可以直接使用它。建立在答案的基础上使用/dev/random、/dev/urandom生成随机数据arr
,这将用n
随机的 32 位数字填充 shell 数组:
n=10
arr=( $(od -vAn -N $((n*4)) -tu4 < /dev/urandom) )
(故意使用分词,IFS
不得包含数字。)
答案2
你可以这样做:
(( my_rnd = (RANDOM << 17) | (RANDOM << 2) | (RANDOM & 3) ))
也就是说,取第一个 RANDOM 的所有 15 位,移位 17 位,另一个 RANDOM 的另外 15 位,移位 2 位,以及第三个 RANDOM 的额外 2 位(较低的,您也可以用于RANDOM >> 13
较高的,至少在旧版本中bash
明显更多随机的)。