Ajout du -r
option (mode inverse) à xxd -b
ne fonctionne pas réellement comme prévu, car xxd ne prend tout simplement pas en charge la combinaison de ces deux drapeaux (il ignore -b
si les deux sont donnés). Au lieu de cela, vous devez d'abord convertir les bits en hexagone vous-même. Par exemple comme ceci :
( echo 'obase=16;ibase=2'; sed -Ee 's/[01]{4}/;\0/g' instructions.txt ) | bc | xxd -r -p > instructions.bin
Explication complète :
- La partie entre parenthèses crée un
bc
scénario. Il définit d'abord la base d'entrée sur binaire (2) et la base de sortie sur hexadécimal (16). Après cela, lesed
la commande imprime le contenu deinstructions.txt
avec un point-virgule entre chaque groupe de 4 bits, ce qui correspond à 1 chiffre hexadécimal. Le résultat est redirigé versbc
. - Le point-virgule est un séparateur de commande en
bc
, donc tout ce que le script fait est d'imprimer chaque entier d'entrée (après conversion de base). - La sortie de
bc
est une séquence de chiffres hexadécimaux, qui peut être convertie en un fichier avec l'habituelxxd -r -p
.
Sortie :
$ hexdump -Cv instructions.bin
00000000 00 00 00 13 02 d1 20 83 00 73 02 b3 00 73 04 33 |...... ..s...s.3|
00000010 00 73 64 b3 00 00 00 13 |.sd.....|
00000018
$ xxd -b -c4 instructions.bin
00000000: 00000000 00000000 00000000 00010011 ....
00000004: 00000010 11010001 00100000 10000011 .. .
00000008: 00000000 01110011 00000010 10110011 .s..
0000000c: 00000000 01110011 00000100 00110011 .s.3
00000010: 00000000 01110011 01100100 10110011 .sd.
00000014: 00000000 00000000 00000000 00010011 ....
oneliner pour convertir des chaînes 32 bits de uns et de zéros en binaire correspondant :
$ perl -ne 'print pack("B32", $_)' < instructions.txt > instructions.bin
ce qu'il fait :
perl -ne
itérera sur chaque ligne du fichier d'entrée fourni sur STDIN (instructions.txt
)pack("B32", $_)
prendra une liste de chaînes de 32 bits ($_
que nous venons de lire à partir de STDIN), et le convertir en valeur binaire (vous pouvez également utiliser"b32"
si vous vouliez un ordre croissant des bits à l'intérieur de chaque octet au lieu d'un ordre décroissant des bits ; voirperldoc -f pack
pour plus de détails)print
sortirait alors cette valeur convertie vers STDOUT, que nous redirigeons ensuite vers notre fichier binaireinstructions.bin
vérifier :
$ hexdump -Cv instructions.bin
00000000 00 00 00 13 02 d1 20 83 00 73 02 b3 00 73 04 33 |...... ..s...s.3|
00000010 00 73 64 b3 00 00 00 13 |.sd.....|
00000018
$ xxd -b -c4 instructions.bin
00000000: 00000000 00000000 00000000 00010011 ....
00000004: 00000010 11010001 00100000 10000011 .. .
00000008: 00000000 01110011 00000010 10110011 .s..
0000000c: 00000000 01110011 00000100 00110011 .s.3
00000010: 00000000 01110011 01100100 10110011 .sd.
00000014: 00000000 00000000 00000000 00010011 ....
Ma réponse d'origine était incorrecte - xxd
ne peut accepter ni -p
ou -r
avec -b
...
Étant donné que les autres réponses sont réalisables, et dans l'intérêt d'"une autre manière ", que diriez-vous de ce qui suit :
Entrée
$ cat instructions.txt
00000000000000000000000000010011
00000010110100010010000010000011
00000000011100110000001010110011
00000000011100110000010000110011
00000000011100110110010010110011
00000000000000000000000000010011
Sortie
$ hexdump -Cv < instructions.bin
00000000 00 00 00 13 02 d1 20 83 00 73 02 b3 00 73 04 33 |...... ..s...s.3|
00000010 00 73 64 b3 00 00 00 13 |.sd.....|
00000018
Canalisation bas :
cat instructions.txt \
| tr -d $'\n' \
| while read -N 4 nibble; do
printf '%x' "$((2#${nibble}))"; \
done \
| xxd -r -p \
> instructions.bin
cat
- inutile, mais utilisé pour plus de clartétr -d $'\n'
- supprimer toutes les nouvelles lignes de l'entréeread -N 4 nibble
- lire exactement 4× caractères dans lenibble
variablesprintf '%x' "$((2#${nibble}))"
convertir le quartet de binaire en 1 × caractère hexadécimal$((2#...))
- convertir la valeur donnée de base 2 (binaire) en base 10 (décimal)printf '%x'
- formater la valeur donnée de la base 10 (décimal) à la base 16 (hexadécimal)
xxd -r -p
- inverser (-r
) un vidage simple (-p
) - de l'hexadécimal au binaire brut
Python :
python << EOF > instructions.bin
d = '$(cat instructions.txt | tr -d $'\n')'
print(''.join([chr(int(d[i:i+8],2)) for i in range(0, len(d), 8)]))
EOF
- Un heredoc non cité (
<< EOF
) est utilisé pour obtenir du contenu dans le code Python- Ceci n'est pas efficace si l'entrée devient volumineuse
cat
ettr
- utilisé pour obtenir une entrée propre (une ligne)range(0, len(d), 8)
- obtenir une liste de nombres de 0 à la fin de la chaîned
, en incrémentant 8× caractères à la fois.chr(int(d[i:i+8],2))
- convertir la tranche courante (d[i:i+8]
) du binaire au décimal (int(..., 2)
), puis à un caractère brut (chr(...)
)[ x for y in z]
- compréhension de la liste''.join(...)
- convertir la liste de caractères en une seule chaîneprint(...)
- imprimez-le