![如何使用 macOS 生成随机 64 位有符号整数?](https://linux22.com/image/101574/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20macOS%20%E7%94%9F%E6%88%90%E9%9A%8F%E6%9C%BA%2064%20%E4%BD%8D%E6%9C%89%E7%AC%A6%E5%8F%B7%E6%95%B4%E6%95%B0%EF%BC%9F.png)
我需要生成一些 64 位有符号整数用于测试。
我怎样才能做到这一点?
#!/bin/sh
long=$(????)
答案1
macOS 附带了 Python。使用其random
模块。
python -c 'import random; rng = random.SystemRandom(); print rng.randint(-2**63, 2**63-1)
答案2
合并从 捕获的 2 个 32 位整数/dev/urandom
。应该可以使用od
捕获每个 64 位值史蒂芬的回答,但至少在某些版本的 OS X 上,此操作会失败,并且不会显示相应的错误消息。
#!/bin/sh
low32=$(od -An -td4 -N4 < /dev/urandom)
high32=$(od -An -td4 -N4 < /dev/urandom)
long=$(($low32 + ($high32 << 32) ))
答案3
由于 macOS 具有/dev/urandom
,您应该能够执行以下操作:
od -An -vtd8 -N8 < /dev/urandom
然而,根据那些在实际 macOS 系统上尝试过的人的说法(参见评论),它在那里不起作用。由于 macOS 是经过认证的 Unix 系统,这意味着它是一个错误POSIX 明确指定该命令的行为。 POSIX 唯一未指定的(实现定义的)是字节顺序(我们在这里不关心,因为这都是随机字节)。
或者,您可以在此处使用ksh
/ bash
/ 。尽管 macOS是基于现在的,但最好切换到 bash/zsh(或除使用 32 位算术之外的实现),因为这不是一项功能,因此如果他们决定切换到 macOS,则可能无法在未来版本的 macOS 中使用不同的外壳。zsh
$RANDOM
sh
bash
ksh
mksh
$RANDOM
sh
m=32768 # $RANDOM span
long=$((RANDOM+RANDOM*m+RANDOM*m*m+RANDOM*m*m*m+RANDOM*m*m*m*m))
或者:
long=$((RANDOM|(RANDOM<<15)|(RANDOM<<30)|(RANDOM<<45)|(RANDOM<<60)))
这是 5*15 == 75 位,但会被 shell 截断为 64 位。
在 POSIX 工具箱中,生成随机数的方法是使用awk
s rand()
,所以你可以这样做:
awk 'BEGIN{srand(); printf "%.20g\n", rand() * (2^64) - (2^63)}'
但请注意,对于许多awk
实现(那些基于srand()
的结果的种子time(3)
),如果您在同一秒内运行两次,您将获得相同的输出。
另外,由于浮点数的表示方式,我预计会有一些 64 位数字(如 2 63 -1)永远不会输出。
答案4
您可以将两个 32 位数字附加在一起,例如,
#!/bin/bash
printf '0x%04x%04x\n' $RANDOM $RANDOM
j=$(printf '16#%04x%04x' $RANDOM $RANDOM)
echo $j
echo $(($j))
样本输出
0x5e34562d
16#7cf567f9
2096457721
这是源自 Korn shell (ksh) 的众多功能之一,几年后被复制到 bash 和 zsh。
根据评论 - 您可以附加其他位:
#!/bin/bash
printf '0x%04x%04x\n' $RANDOM $RANDOM
foo=32767
printf '%016x\n' $((foo << 49))
printf '%016x\n' $((foo << 34))
printf '%016x\n' $((foo << 19))
printf '%016x\n' $((foo << 4))
printf '%016x\n' $((foo % 16))
printf '%016x\n' $((foo << 49 |
(foo << 34) |
(foo << 19) |
(foo << 4) |
(foo % 16)))
printf '%d\n' $((foo << 49 |
(foo << 34) |
(foo << 19) |
(foo << 4) |
(foo % 16)))
示例输出:
0x3a1e1184
fffe000000000000
0001fffc00000000
00000003fff80000
000000000007fff0
000000000000000f
ffffffffffffffff
-1