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 diesed
Befehl gibt den Inhalt voninstructions.txt
aus mit einem Semikolon zwischen jeder Gruppe von 4 Bits, was 1 Hex-Ziffer entspricht. Das Ergebnis wird inbc
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 üblichenxxd -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; sieheperldoc -f pack
für weitere Details)print
würde dann diesen konvertierten Wert an STDOUT ausgeben, das wir dann in unsere Binärdateiinstructions.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 verwendettr -d $'\n'
- alle Zeilenumbrüche aus der Eingabe entfernenread -N 4 nibble
- genau lesen 4× Zeichen in dennibble
variabelprintf '%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) umprintf '%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
undtr
- Wird verwendet, um eine saubere (einzeilige) Eingabe zu erhaltenrange(0, len(d), 8)
- Erhalten Sie eine Liste von Zahlen von 0 bis zum Ende der Zeichenfolged
, 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 Zeichenfolgeprint(...)
- ausdrucken