shell 脚本中正确的类型转换,用于 while 循环和模数

shell 脚本中正确的类型转换,用于 while 循环和模数

我正在尝试编写一个脚本来获取随机的、偶数的十六进制数。我发现该openssl命令有一个方便的选项来创建随机十六进制数字。不幸的是,我需要它是均匀的,并且我的脚本在某处存在类型转换错误。 Bash 认为我新生成的十六进制数字是一个字符串,因此当我尝试将其修改为 2 时,脚本失败。这是我到目前为止所拥有的:

...
hexVal="$(openssl rand -hex 1)"
while [ `expr $hexVal % 2` -ne 0 ]
do
    hexVal="$(openssl rand -hex 1)"
done
...

我也尝试过其他各种组合,但均无济于事。如果有人能告诉我我的语法有什么问题,我将不胜感激。

答案1

使用bash

要生成十六进制偶数随机数:

$ printf '%x\n' $((2*$RANDOM))
d056

或者:

$ hexVal=$(printf '%x\n' $((2*$RANDOM)))
$ echo $hexVal
f58a

要将输出限制为较小的数字,请使用 modulo, %

$ printf '%x\n' $(( 2*$RANDOM % 256 ))
4a

使用openssl

如果您确实想使用循环解决方案openssl

while hexVal="$(openssl rand -hex 1)"
do
    ((0x$hexVal % 2 == 0)) && break
done

0x信号表明后面的数字是十六进制。

bash 中的数字转换规则

man bash

以 0 开头的常量被解释为八进制数。 前导 0x 或 0X 表示十六进制。 否则,数字采用 [base#]n 形式,其中可选基数是 2 到 64 之间的十进制数,表示算术基数,n 是该基数中的数字。如果省略 base#,则使用基数 10。指定n时,大于9的数字按小写字母、大写字母、@和_的顺序表示。如果底数小于或等于 36,则小写和大写字母可以互换使用来表示 10 到 35 之间的数字。 [强调]

答案2

那这个呢

printf "%0x\n" $(( ($RANDOM*2) & 0xff))

答案3

hexVal=1

while (( 16#$hexVal % 2))
do
    hexVal=$(openssl rand -hex 1)
done

printf "%x [%d]\n"  0x$hexVal  0x$hexVal

相关内容