O xxd pode ser usado para gerar a representação binária do número hexadecimal, não uma string?

10

Eu gostaria de gerar um pacote binário bruto a partir de hex na linha de comando com a finalidade de testar um protocolo. Espero que seja mais simples fazê-lo dessa maneira do que escrever uma aplicação.

Aqui está o que acontece atualmente:

echo '0A' | xxd  -b
0000000: 00110000 01000001 00001010

O que eu gostaria de ter é:

echo '0A' | xxd  -b
0000000: 00001010    

ou

echo '0A' | xxd  -b
0000000: 01010000    

Desde que eu não tenho certeza sobre o endianess necessário. Eu gostaria de poder alterá-lo quando necessário. Isso é possível?

TheMeaningfulEngineer
fonte

Respostas:

9

echo '0A'produz três caracteres 0 A NL:; xxd -bimprimirá esses três caracteres em binário. Se você quiser apenas o byte único cujo valor é 10 (ou seja, hexadecimal A), você pode escrever (em bash):

echo -n $'\x0A'
      ^ ^  ^
      | |  |
      | |  +-- `\x` indicates a hexadecimal escape
      | +----- Inside a $' string, escapes are interpreted
      +------- -n suppresses the trailing newline

Uma alternativa melhor seria printf '\x0A'; printf interpreta seqüências de escape na string de formato e não gera novas linhas implícitas. (Esta é a solução compatível com Posix, que deve funcionar em qualquer shell compatível com Posix.) Ainda outra possibilidade de bash é echo -n -e '\x0A'; o -esinalizador (não padrão) pede que o eco interprete as seqüências de escape.

echo '1' | xxd -bnão produzirá o equivalente a hex 50, porque xxdnão sabe que 0Aé um número hexadecimal e 1não é. Além disso, o código ascii para o caractere 1é hexadecimal 31, não 50.

Endianness não afeta bytes. A ordem dos bits dentro de um byte é inteiramente conceitual até que o byte seja transmitido por uma linha serial e mesmo assim seja visível apenas com um osciloscópio ou algo semelhante.

rici
fonte
Desculpe pelo 50. É um erro de digitação. Corrigindo agora #
TheMeaningfulEngineer
7

Se você deseja a saída binária para uma sequência de dígitos hexadecimais xxd -r -p,. Por exemplo:

 $ echo '0A0B0C0D' | xxd -r -p | xxd -b
 0000000: 00001010 00001011 00001100 00001101                    ....

converte 0A0B0C0D em quatro bytes de binário (primeira chamada para xxd) e depois converte-o novamente para ser imprimível (segunda chamada). Você diz que deseja uma saída binária, mas os exemplos que está tentando são uma representação imprimível.

Não sei de nada em que o endianismo seja ambíguo no nível da mordidela, como você sugere no seu segundo exemplo. A conversão em xxd é um byte puro por vez, não assumindo que eles representem um número de vários bytes específico.

jtniehof
fonte
2

Sim, você pode usar xxdisso, mas pode não gostar do formato de entrada. No seu exemplo, 0x0a é o valor hexadecimal de uma nova linha ASCII. Você pode criar um arquivo com uma única nova linha e usar xxdpara criar a listagem:

$ xxd one_line_file
0000000: 0a                                       .

Você pode obter uma única nova linha xxddessa saída se fornecer os sinalizadores adequados:

$ echo "0000000: 0a" | xxd -r > another_one_line_file
$ xxd another_one_line_file
0000000: 0a 

xxdtem um formato de saída bastante agradável, não acho que seria muito oneroso criar seus pacotes usando um editor de texto e depois usá xxd -r-lo para acessar o binário. .

Bruce Ediger
fonte