Como obter representações binárias de strings no Shell?

2

Estou usando openssl dgst -sha1 -binary para obter valores hash das minhas strings em formato binário.

(Estou usando -binary flag porque minha versão do openssl adiciona "stdout" antes de cada valor de hash na saída padrão e -binary ajuda a evitá-lo, portanto é mais fácil armazenar os resultados de hash em formato binário para mais processamento (para que eu possa usar apenas xxd -p quando eu quiser valores hexadecimais em vez de cortar manualmente " stdout " de cada string)

Portanto, a saída binária de openssl dgst -sha1 -binary para um "Hello!" string no console do Cygwin será semelhante a: _▒▒ "q▒% ▒a▒▒▒▒. & C▒0N▒Q▒▒vH & 8i

Agora eu crio uma nova variável com esse resultado e a concateno com outra variável, cujo valor não está no formato binário (ou seja, "World"). Então minha nova variável agora parece

_▒▒ "q▒% ▒a▒▒▒▒. & C▒0N▒Q▒▒vH & 8iWorld

Em seguida, gerei outro hash para essa string concatenada e compararei com a que obtive usando bibliotecas de hashing Java padrão ( MessageDigest ). Nesta etapa, no entanto, os hashes obtidos por meio do shell e do Java não correspondem (e eu preciso obter exatamente o mesmo valor que o gerado no lado do Java).

Então, suponho que minha string "World" também esteja em formato binário para corresponder à minha saída de hash Java (porque, desde que eu gere hashes para valores binários concatenados, todos os hashes coincidem). No entanto, não sei como converter minha string "World" em formato binário no shell. Alguma idéia?

    
por C_U 19.01.2015 / 13:07

1 resposta

5

Você não pode armazenar dados binário (dados binários geralmente se referem a dados com valores de byte arbitrários, não apenas valores de byte que formam caracteres válidos, mas não são especiais) em bash variables as bash não suporta o armazenamento do valor de 0 byte em suas variáveis (e lembre-se de que você não pode passar tais strings em argumentos para comandos como são strings delimitadas por NUL).

Você pode em zsh embora. Lembre-se também que a substituição de comandos retira caracteres de nova linha (0xa bytes, talvez diferentes no Cygwin), então é melhor usar read aqui:

$ echo 323 | openssl dgst -sha1 -binary | hd
00000000  3a 8b 03 4a 5d 00 e9 07  b2 9e 0a 61 b3 54 db 45  |:..J]......a.T.E|
00000010  63 4b 37 b0                                       |cK7.|
00000014

Veja como isso contém um caractere de 0 byte e nova linha (0xa)

$ echo 323 | openssl dgst -sha1 -binary | IFS= LC_ALL=C read -ru0 -k20 var &&
  var=${var}World
$ printf %s $var | hd
00000000  3a 8b 03 4a 5d 00 e9 07  b2 9e 0a 61 b3 54 db 45  |:..J]......a.T.E|
00000010  63 4b 37 b0 57 6f 72 6c  64                       |cK7.World|
00000019

Note novamente que você só pode passar essa variável para os comandos incorporados ( printf ...).

Agora, se tudo o que você quer é fazer hash novamente, então é só

(echo 323 | openssl dgst -sha1 -binary; printf %s World) |
  openssl dgst -sha1 -binary

não há necessidade de uma variável.

    
por 19.01.2015 / 13:25