GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Konvertieren Sie eine Textdatei von Bits in eine Binärdatei

Hinzufügen des -r Option (Umkehrmodus) auf xxd -b funktioniert eigentlich nicht wie beabsichtigt, da xxd die Kombination dieser beiden Flags einfach nicht unterstützt (es ignoriert -b wenn beides gegeben ist). Stattdessen müssen Sie die Bits zuerst selbst in Hex umwandeln. Zum Beispiel so:

( echo 'obase=16;ibase=2'; sed -Ee 's/[01]{4}/;\0/g' instructions.txt ) | bc | xxd -r -p > instructions.bin

Vollständige Erklärung:

  • Der Teil innerhalb der Klammern erzeugt eine bc Skript. Es setzt zuerst die Eingangsbasis auf binär (2) und die Ausgangsbasis auf hexadezimal (16). Danach die sed Befehl gibt den Inhalt von instructions.txt aus mit einem Semikolon zwischen jeder Gruppe von 4 Bits, was 1 Hex-Ziffer entspricht. Das Ergebnis wird in bc geleitet .
  • Das Semikolon ist ein Befehlstrennzeichen in bc , also gibt das Skript nur jede eingegebene Ganzzahl wieder aus (nach der Basiskonvertierung).
  • Die Ausgabe von bc ist eine Folge von Hex-Ziffern, die mit dem üblichen xxd -r -p in eine Datei umgewandelt werden kann .

Ausgabe:

$ 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, um 32-Bit-Strings aus Einsen und Nullen in entsprechende Binärdateien umzuwandeln:

$ perl -ne 'print pack("B32", $_)' < instructions.txt > instructions.bin

was es tut:

  • perl -ne durchläuft jede Zeile der Eingabedatei, die auf STDIN bereitgestellt wird (instructions.txt )
  • pack("B32", $_) nimmt eine Zeichenfolgenliste von 32 Bit ($_ die wir gerade aus STDIN gelesen haben) und in einen Binärwert umwandeln (alternativ könnten Sie "b32" verwenden wenn Sie in jedem Byte eine aufsteigende Bitreihenfolge anstelle einer absteigenden Bitreihenfolge wünschen; siehe perldoc -f pack für weitere Details)
  • print würde dann diesen konvertierten Wert an STDOUT ausgeben, das wir dann in unsere Binärdatei instructions.bin umleiten

überprüfen:

$ 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  ....

Meine ursprüngliche Antwort war falsch - xxd kann weder -p akzeptieren oder -r mit -b ...

Angesichts der Tatsache, dass die anderen Antworten praktikabel sind und im Interesse eines "anderen Weges ", wie wäre es mit Folgendem:

Eingabe

$ cat instructions.txt
00000000000000000000000000010011
00000010110100010010000010000011
00000000011100110000001010110011
00000000011100110000010000110011
00000000011100110110010010110011
00000000000000000000000000010011

Ausgabe

$ 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

Bash-Pipeline:

cat instructions.txt \
    | tr -d $'\n' \
    | while read -N 4 nibble; do 
        printf '%x' "$((2#${nibble}))"; \
      done \
    | xxd -r -p \
    > instructions.bin
  • cat - unnötig, aber zur Verdeutlichung verwendet
  • tr -d $'\n' - alle Zeilenumbrüche aus der Eingabe entfernen
  • read -N 4 nibble - genau lesen 4× Zeichen in den nibble variabel
  • printf '%x' "$((2#${nibble}))" Wandeln Sie das Nibble von binär in 1× Hexadezimalzeichen
      um
    • $((2#...)) - Wandeln Sie den angegebenen Wert von Basis 2 (binär) in Basis 10 (dezimal) um
    • printf '%x' - formatiert den gegebenen Wert von Basis 10 (dezimal) zu Basis 16 (hexadezimal)
  • xxd -r -p - rückwärts (-r ) ein einfaches Dump (-p ) - von Hexadezimal zu Rohbinär

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
  • Ein nicht zitiertes Heredoc (<< EOF ) wird verwendet, um Inhalte in den Python-Code
      zu bekommen
    • Dies ist nicht effizient, wenn die Eingabe groß wird
  • cat und tr - Wird verwendet, um eine saubere (einzeilige) Eingabe zu erhalten
  • range(0, len(d), 8) - Erhalten Sie eine Liste von Zahlen von 0 bis zum Ende der Zeichenfolge d , Schritt für Schritt 8× Zeichen auf einmal.
  • chr(int(d[i:i+8],2)) - Konvertiere das aktuelle Slice (d[i:i+8] ) von binär zu dezimal (int(..., 2) ) und dann zu einem Rohzeichen (chr(...) )
  • [ x for y in z] - Listenverständnis
  • ''.join(...) - Konvertieren Sie die Liste der Zeichen in eine einzelne Zeichenfolge
  • print(...) - ausdrucken

Linux
  1. Wie entferne ich „Binärdaten“ aus einer Textdatei (z. B. Bash_history)?

  2. Warum betrachtet Grep eine Datei als binär?

  3. Eine .gz-Datei entpacken, um eine Textdatei zu erhalten, aber eine Binärdatei erhalten?

  4. Wie konvertiert man eine ausführbare Linux-Datei (binär) in eine Windows-Exe-Datei?

  5. Wie füge ich Text an eine Datei an?

So konvertieren Sie eine Windows-Datei in eine UNIX-Datei

Text an das Ende einer Textdatei anhängen?

Wie kann man unter Linux Binärdateien von Textdateien unterscheiden?

Bild in Text umwandeln

Was könnte dazu führen, dass der Dateibefehl in Linux eine Textdatei als Binärdaten meldet?

Wie konvertiert man bestimmten Text aus einer Liste in Großbuchstaben?