Como posso gerar um inteiro assinado de 64 bits aleatório com o macOS?

3

Eu preciso gerar um inteiro assinado de 64 bits para teste.

Como posso fazer isso?

#!/bin/sh
long=$(????)
    
por Jin Kwon 23.12.2016 / 08:55

4 respostas

3

Combine 2 inteiros de 32 bits capturados de /dev/urandom . Deve ser possível usar od para capturar um único valor de 64 bits por resposta de Stéphane , mas em menos algumas versões do OS X isto falha sem uma mensagem de erro apropriada.

#!/bin/sh
low32=$(od -An -td4 -N4 < /dev/urandom)
high32=$(od -An -td4 -N4 < /dev/urandom)
long=$(($low32 + ($high32 << 32) ))
    
por 23.12.2016 / 14:53
4

O macOS vem com o Python. Use o módulo random .

python -c 'import random; rng = random.SystemRandom(); print rng.randint(-2**63, 2**63-1)
    
por 25.12.2016 / 02:06
2

Como o macOS tem /dev/urandom , você deve ser capaz de fazer:

od -An -vtd8 -N8 < /dev/urandom

No entanto, de acordo com aqueles que tentaram em um sistema macOS real (veja os comentários), ele não funciona lá. Como o macOS deve ser um sistema Unix certificado, isso significa que é um bug, pois o POSIX especifica claramente o comportamento desse comando . A única coisa que POSIX deixa de especificar (implementação definida) é a ordem de bytes (que não nos importamos aqui, pois são todos os bytes aleatórios).

Como alternativa, você pode usar ksh / bash / zsh $RANDOM aqui. Mesmo que o macOS ' sh seja baseado em bash hoje em dia, seria melhor mudar para bash / zsh (ou ksh implementações diferentes de mksh cuja utilização aritmética de 32bits) como $RANDOM não é sh feature, portanto, pode não funcionar na versão futura do macOS se eles decidirem mudar para um shell diferente.

m=32768 # $RANDOM span
long=$((RANDOM+RANDOM*m+RANDOM*m*m+RANDOM*m*m*m+RANDOM*m*m*m*m))

ou:

long=$((RANDOM|(RANDOM<<15)|(RANDOM<<30)|(RANDOM<<45)|(RANDOM<<60)))

São 5 * 15 == 75 bits, mas serão truncados para 64 bits pelo shell.

Na caixa de ferramentas POSIX, a maneira de gerar números aleatórios é com awk ' rand() , então você pode fazer:

awk 'BEGIN{srand(); printf "%.20g\n", rand() * (2^64) - (2^63)}'
Tenha em mente que com muitas awk implementações (aquelas que baseiam a srand() semente no resultado de time(3) ), você obterá a mesma saída se você executá-lo duas vezes no mesmo segundo.

Além disso, devido à maneira como os números de ponto flutuante são representados, eu esperaria que houvesse alguns números de 64 bits (como 2 63 -1) que ele nunca produziria.

    
por 23.12.2016 / 12:59
-2

Você pode adicionar dois números de 32 bits juntos, por exemplo,

#!/bin/bash
printf '0x%04x%04x\n' $RANDOM $RANDOM
j=$(printf '16#%04x%04x' $RANDOM $RANDOM)
echo $j
echo $(($j))

Exemplo de saída

0x5e34562d 
16#7cf567f9
2096457721

Este é um dos muitos recursos originados no shell Korn (ksh), copiados para bash e zsh alguns anos depois.

Por comentário - você pode acrescentar bits adicionais:

#!/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)))

Exemplo de saída:

0x3a1e1184     
fffe000000000000
0001fffc00000000
00000003fff80000
000000000007fff0
000000000000000f
ffffffffffffffff
-1
    
por 23.12.2016 / 12:47