如何配置 RANDOM 以获得相同的 32 位范围的随机数,例如使用 SRANDOM?

如何配置 RANDOM 以获得相同的 32 位范围的随机数,例如使用 SRANDOM?

环境:

  • 德班
  • 重击

已知的情况:

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 是代表第二个值的位。

类似地,要获得任意数量的位,您可以使用RANDOMSRANDOM来生成至少那么多位,并与 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/urandomarc4random使用更好的算法实现,因此如果可用,您应该使用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明显更多随机的)。

相关内容