Tipo de conversão adequado em um script de shell para uso com loop e módulo de while

3

Estou tentando escrever um script para obter um número hexadecimal aleatório. Eu encontrei o comando openssl tem uma opção conveniente para criar números hexadecimais aleatórios. Infelizmente, eu preciso que ele seja par e meu script tem um erro de transmissão de tipo em algum lugar. Bash acha que meu número hexadecimal recém-gerado é uma string, então quando eu tento mod-lo por 2, o script falha. Aqui está o que eu tenho até agora:

...
hexVal="$(openssl rand -hex 1)"
while [ 'expr $hexVal % 2' -ne 0 ]
do
    hexVal="$(openssl rand -hex 1)"
done
...

Eu tentei várias outras combinações também, sem sucesso. Se alguém pudesse me dizer o que está errado com a minha sintaxe, seria muito apreciado.

    
por resu 16.06.2016 / 00:40

3 respostas

3

Usando o bash

Para gerar um número par aleatório em hexadecimal:

$ printf '%x\n' $((2*$RANDOM))
d056

Ou:

$ hexVal=$(printf '%x\n' $((2*$RANDOM)))
$ echo $hexVal
f58a

Para limitar a saída a números menores, use modulo, % :

$ printf '%x\n' $(( 2*$RANDOM % 256 ))
4a

Usando o openssl

Se você realmente quiser usar uma solução de loop com openssl :

while hexVal="$(openssl rand -hex 1)"
do
    ((0x$hexVal % 2 == 0)) && break
done

O 0x indica que o número a seguir é hexadecimal.

Regras para lançar números no bash

De man bash :

Constants with a leading 0 are interpreted as octal numbers. A leading 0x or 0X denotes hexadecimal. Otherwise, numbers take the form [base#]n, where the optional base is a decimal number between 2 and 64 representing the arithmetic base, and n is a number in that base. If base# is omitted, then base 10 is used. When specifying n, the digits greater< than 9 are represented by the lowercase letters, the uppercase letters, @, and _, in that order. If base is less than or equal to 36, lowercase and uppercase letters may be used interchangeably to represent numbers between 10 and 35. [Emphasis added]

    
por 16.06.2016 / 00:54
0

E quanto a isso,

printf "%0x\n" $(( ($RANDOM*2) & 0xff))
    
por 16.06.2016 / 00:55
0
hexVal=1

while (( 16#$hexVal % 2))
do
    hexVal=$(openssl rand -hex 1)
done

printf "%x [%d]\n"  0x$hexVal  0x$hexVal
    
por 16.06.2016 / 01:19