Peut-on utiliser xxd pour afficher la représentation binaire d'un nombre hexadécimal, pas une chaîne?

10

Je voudrais générer un paquet binaire brut à partir de hex dans la ligne de commande dans le but de tester un protocole. J'espère que c'est plus simple de le faire de cette façon que d'écrire une application.

Voici ce qui se passe actuellement:

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

Ce que j'aimerais avoir c'est:

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

ou

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

Comme je ne suis pas sûr de l'endianisme requis. J'aimerais pouvoir le changer si nécessaire. Est-ce réalisable?

TheMeaningfulEngineer
la source

Réponses:

9

echo '0A'produit trois caractères 0 A NL:; xxd -bimprimera ensuite ces trois caractères en binaire. Si vous vouliez juste le seul octet dont la valeur est 10 (c'est-à-dire hexadécimal A), vous pourriez écrire (en bash):

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

Une meilleure alternative serait printf '\x0A'; printf interprète les séquences d'échappement dans la chaîne de format et ne génère pas de sauts de ligne implicites. (Il s'agit de la solution compatible Posix, qui devrait fonctionner sur n'importe quel shell compatible Posix.) Encore une autre possibilité bash est echo -n -e '\x0A'; l' -eindicateur (non standard) demande à écho d'interpréter les séquences d'échappement.

echo '1' | xxd -bne produira pas l'équivalent de hex 50, car xxdne sait pas que 0Ac'est un nombre hexadécimal et 1ne l'est pas. De plus, le code ascii du personnage 1est hexadécimal 31, non 50.

L'endianité n'affecte pas les octets. L'ordre des bits à l'intérieur d'un octet est entièrement conceptuel jusqu'à ce que l'octet soit transmis sur une ligne série et même alors, il n'est visible qu'avec un oscilloscope ou quelque chose de similaire.

rici
la source
Désolé pour le 50. C'est une faute de frappe.
Réparer
7

Si vous voulez que la sortie binaire pour une chaîne de caractères hexadécimaux, xxd -r -p. Par exemple:

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

convertit 0A0B0C0D en quatre octets de binaire (premier appel à xxd), puis le reconvertit pour être imprimable (deuxième appel). Vous dites que vous voulez une sortie binaire, mais les exemples que vous essayez sont une représentation imprimable.

Je ne connais rien où l'endianité soit ambiguë au niveau du grignotage, comme vous l'imaginez dans votre deuxième exemple. La conversion dans xxd est un octet pur à la fois, ne supposant pas qu'ils représentent un nombre à plusieurs octets particulier.

jtniehof
la source
2

Oui, vous pouvez le xxdfaire, mais vous n'aimerez peut-être pas le format d'entrée. Dans votre exemple, 0x0a est la valeur hexadécimale d'une nouvelle ligne ASCII. Vous pouvez créer un fichier avec une seule nouvelle ligne, puis utiliser xxdpour créer la liste:

$ xxd one_line_file
0000000: 0a                                       .

Vous pouvez obtenir une seule nouvelle ligne à xxdpartir de cette sortie si vous lui donnez les indicateurs appropriés:

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

xxda un format de sortie assez agréable, je ne pense pas que ce serait trop onéreux de créer vos paquets à l'aide d'un éditeur de texte, puis d'utiliser xxd -rpour passer au binaire. .

Bruce Ediger
la source