GNU/Linux >> Tutoriels Linux >  >> Linux

convertir un fichier texte de bits en fichier binaire

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, le sed la commande imprime le contenu de instructions.txt avec un point-virgule entre chaque groupe de 4 bits, ce qui correspond à 1 chiffre hexadécimal. Le résultat est redirigé vers bc .
  • 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'habituel xxd -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 ; voir perldoc -f pack pour plus de détails)
  • print sortirait alors cette valeur convertie vers STDOUT, que nous redirigeons ensuite vers notre fichier binaire instructions.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ée
  • read -N 4 nibble - lire exactement 4× caractères dans le nibble variables
  • printf '%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 et tr - 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îne d , 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îne
  • print(...) - imprimez-le

Linux
  1. Comment supprimer les "données binaires" d'un fichier texte (par exemple, Bash_history) ?

  2. Qu'est-ce qui fait que Grep considère qu'un fichier est binaire ?

  3. Décompresser un fichier .gz pour obtenir un fichier texte mais obtenir un fichier binaire ? ?

  4. Comment distinguer le binaire des fichiers texte sous Linux

  5. Comment ajouter du texte à un fichier ?

Comment convertir un fichier Windows en un fichier UNIX

Utiliser Uniq sur le texte Unicode ?

Ajouter du texte à la fin d'un fichier texte ?

Comment convertir un fichier exécutable Linux (binaire) en fichier exe Windows ?

Convertir le mode binaire en mode texte et l'option inverse

Comment puis-je convertir des données textuelles à deux valeurs en binaire (représentation binaire)