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ビットですが、シェルでは64ビットに切り捨てられます。

POSIX ツールボックスで乱数を生成する方法はawks を使用するrand()ことですので、次のようにできます。

awk 'BEGIN{srand(); printf "%.20g\n", rand() * (2^64) - (2^63)}'

ただし、多くの実装(結果のシードawkに基づく実装)の場合、同じ秒に2回実行すると同じ出力が得られます。srand()time(3)

また、浮動小数点数の表現方法によって決して出力されないいくつかの64ビット数(2 63 -1など)があると予想されます。

答え4

たとえば、2 つの 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シェル(ksh)から派生した多くの機能の1つであり、数年後に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

関連情報