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

8

Eu gostaria de gerar um pacote binário bruto de hex na linha de comando com o propósito de testar um protocolo. Espero que seja mais simples fazer isso 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 mudá-lo quando necessário. Isso é possível?

    
por TheMeaningfulEngineer 04.02.2014 / 15:54

3 respostas

6

echo '0A' produz três caracteres: 0 A NL ; xxd -b imprimirá esses três caracteres em binário. Se você quisesse apenas o byte único cujo valor é 10 (ou seja, hexadecimal A ), você poderia escrever (no 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' ; O printf interpreta as 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.) Outra possibilidade bash é echo -n -e '\x0A' ; o sinalizador -e (não padrão) solicita que o echo interprete as seqüências de escape.

Não tenho ideia de por que você esperaria que echo '1' | xxd -b emitisse o equivalente a hex 50 . Como você espera que xxd entenda que 0A é um número hexadecimal e 1 não é? Além disso, por que 50 ? (O código ascii para o caractere 1 é hex 31 .)

O endianness não afeta os bytes. A ordem dos bits dentro de um byte é totalmente conceitual até que o byte seja transmitido por uma linha serial e, mesmo assim, ele só é visível com um osciloscópio ou algo semelhante.

    
por 04.02.2014 / 16:18
5

Se você quiser a saída binária para uma seqüê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, em seguida, converte-o de volta para ser imprimível (segunda chamada). Você diz que quer uma saída binária, mas os exemplos que você está tentando são uma representação imprimível.

Eu não sei de nada em que o endianness é ambíguo no nível do nibble, como você sugere em seu segundo exemplo. A conversão em xxd é um byte puro de cada vez, não assumindo que eles representem um determinado número de múltiplos bytes.

    
por 30.03.2015 / 18:02
2

Sim, você pode usar xxd para fazer isso, mas talvez não goste do formato de entrada. Do seu exemplo, 0x0a é o valor hexadecimal de uma nova linha ASCII. Você pode criar um arquivo com uma única nova linha e usar xxd para criar a listagem:

$ xxd one_line_file
0000000: 0a                                       .

Você pode obter uma única nova linha de saída de xxd dessa saída se der a ela os sinalizadores adequados:

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

xxd tem um ótimo formato de saída, eu não acho que seria muito oneroso criar seus pacotes usando um editor de texto, então use xxd -r para ir para binário.                                       .

    
por 04.02.2014 / 18:03