如何使用 macOS 生成随机 64 位有符号整数?

如何使用 macOS 生成随机 64 位有符号整数?

我需要生成一些 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$RANDOMshbashkshmksh$RANDOMsh

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 工具箱中,生成随机数的方法是使用awks 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

相关内容