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

캡처된 두 개의 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기반으로 하는 구현 )의 경우 동일한 초에 두 번 실행하면 동일한 출력을 얻게 됩니다.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 셸(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

관련 정보