Wie kann ich eine binäre Datei erstellen , instructions.binwie die gleichen Daten instructions.txt. Mit anderen Worten, die .binDatei sollte die gleichen 192 Bits enthalten, die sich in der .txtDatei befinden, mit 32 Bits pro Zeile. Ich benutze Bash unter Ubuntu Linux. Ich habe versucht zu verwenden, xxd -b instructions.txtaber die Ausgabe ist viel länger als 192 Bit.
perl -nedurchläuft jede Zeile der auf STDIN ( instructions.txt) bereitgestellten Eingabedatei
pack("B32", $_)nimmt eine Zeichenfolgenliste mit 32 Bits ( $_die wir gerade aus STDIN gelesen haben) und konvertiert sie in einen Binärwert (Sie können sie auch verwenden, "b32"wenn Sie eine aufsteigende Bitreihenfolge innerhalb jedes Bytes anstelle einer absteigenden Bitreihenfolge wünschen; siehe perldoc -f packweitere Einzelheiten).
print würde dann diesen konvertierten Wert in STDOUT ausgeben, den wir dann in unsere Binärdatei umleiten instructions.bin
Das Hinzufügen der -rOption (umgekehrter Modus) zu xxd -bfunktioniert nicht wie beabsichtigt, da xxd das Kombinieren dieser beiden Flags einfach nicht unterstützt (es wird ignoriert, -bwenn beide angegeben sind). Stattdessen müssen Sie die Bits zuerst konvertieren, um sich selbst zu verhexen. 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 in den Klammern erstellt ein bcSkript. Zunächst wird die Eingangsbasis auf binär (2) und die Ausgangsbasis auf hexadezimal (16) gesetzt. Danach seddruckt der Befehl den Inhalt von instructions.txtmit einem Semikolon zwischen jeder Gruppe von 4 Bits, was einer hexadezimalen Ziffer entspricht. Das Ergebnis wird weitergeleitet bc.
Das Semikolon ist ein Befehlstrennzeichen in bc. Das Skript druckt also nur jede Eingabe-Ganzzahl zurück (nach der Basiskonvertierung).
Die Ausgabe von bcist eine Folge von Hex-Ziffern, die mit den üblichen in eine Datei konvertiert werden können xxd -r -p.
Entschuldigung, es gibt immer noch einen Endianness-Fehler. Arbeiten Sie daran, es zu reparieren!
Nomadentyp
1
Eigentlich ist es in Ordnung. Ich war früher verwirrt, als ich im letzten xxd-Befehl die falsche Ausgabebreite verwendet habe.
Nomadentyp
1
Ich habe das Skript getestet und es funktioniert aber gibt aus : (standard_in) 1: syntax error. Können Sie erklären, worauf syntax errores sich bezieht oder warum dies geschieht? Passiert das auch auf Ihrer Maschine?
Hinweis: In vielen Shells |am Ende einer Zeile funktioniert dies wie ein Backslash: Der Befehl fährt mit der nächsten Zeile fort. Auf diese Weise können Sie einige Backslashes entfernen. Ich bin mir nicht sicher, ob die Verwendung von Pipe-Symbolen nach LFs Ihre informierte Entscheidung war. Ich erwähne den anderen Weg, falls Sie es nicht wussten.
Kamil Maciorowski
1
Ich wusste es nicht, danke! Ich mag es, die Pipeline in logische Zeilen zu unterteilen und die Pipes |(oder Weiterleitungen >, boolesche Operatoren &&usw.) aus Gründen der Sichtbarkeit / Klarheit explizit im Vordergrund zu haben ... vielleicht eine stilistische / bevorzugte Sache.
Attie
1
Nach einigen Überlegungen kann ich anfangen, diesen Stil zu verwenden, da man erkennen kann, dass die beiden Linien verbunden sind, indem man eine von ihnen untersucht. Wenn |am Ende die nächste Zeile wie ein eigenständiger Befehl aussieht, kann dies verwirrend sein. Aus diesem Grund dachte ich, der Stil könnte Ihre informierte Entscheidung sein.
Sie können auch versuchen, dies auf der CodeGolf SE-Website zu veröffentlichen, aber hier ist meine alternative Python-Version (nur für Kick-Challenge):
python -c "import sys,struct;[sys.stdout.buffer.write(struct.pack('!i',int(x,2)))for x in sys.stdin]" \
< input.txt > output.bin
Angenommen, Sie input.txtenthalten Ihre Daten und sind mit 32 Zeichen pro Zeile formatiert.
Dies verwendet das Python 3- structPaket und das Schreiben / Lesen von stdin / out. (In Python 2 wäre es kürzer gewesen).
(standard_in) 1: syntax error
. Können Sie erklären, woraufsyntax error
es sich bezieht oder warum dies geschieht? Passiert das auch auf Ihrer Maschine?Meine ursprüngliche Antwort war falsch -
xxd
kann weder akzeptieren-p
noch-r
mit-b
...Angesichts der Tatsache, dass die anderen Antworten praktikabel sind und im Interesse eines " anderen Weges ", wie wäre es mit Folgendem:
Eingang
Ausgabe
Bash-Pipeline:
cat
- unnötig, aber aus Gründen der Klarheit verwendettr -d $'\n'
- Entfernen Sie alle Zeilenumbrüche aus der Eingaberead -N 4 nibble
- Lesen Sie genau 4 × Zeichen in dienibble
Variableprintf '%x' "$((2#${nibble}))"
Konvertieren Sie das Halbbyte von binär in 1 × Hex-Zeichen$((2#...))
- Konvertieren Sie den angegebenen Wert von Basis 2 (binär) in Basis 10 (dezimal).printf '%x'
- Formatieren Sie den angegebenen Wert von Basis 10 (dezimal) bis Basis 16 (hexadezimal).xxd -r -p
- reverse (-r
) a plain dump (-p
) - von hexadezimal zu roh binärPython:
<< EOF
) wird verwendet, um Inhalte in den Python-Code zu bringencat
undtr
- wird verwendet, um eine saubere (einzeilige) Eingabe zu erhaltenrange(0, len(d), 8)
- Holen Sie sich eine Liste mit Zahlen von 0 bis zum Ende der Zeichenfolged
, wobei Sie jeweils 8 × Zeichen eingeben.chr(int(d[i:i+8],2))
- Konvertieren Sie das aktuelle Slice (d[i:i+8]
) von Binär in Dezimal (int(..., 2)
) und dann in ein Rohzeichen (chr(...)
).[ x for y in z]
- Listenverständnis''.join(...)
- Konvertieren Sie die Liste der Zeichen in eine einzelne Zeichenfolgeprint(...)
- Druck esquelle
|
am Ende einer Zeile funktioniert dies wie ein Backslash: Der Befehl fährt mit der nächsten Zeile fort. Auf diese Weise können Sie einige Backslashes entfernen. Ich bin mir nicht sicher, ob die Verwendung von Pipe-Symbolen nach LFs Ihre informierte Entscheidung war. Ich erwähne den anderen Weg, falls Sie es nicht wussten.|
(oder Weiterleitungen>
, boolesche Operatoren&&
usw.) aus Gründen der Sichtbarkeit / Klarheit explizit im Vordergrund zu haben ... vielleicht eine stilistische / bevorzugte Sache.|
am Ende die nächste Zeile wie ein eigenständiger Befehl aussieht, kann dies verwirrend sein. Aus diesem Grund dachte ich, der Stil könnte Ihre informierte Entscheidung sein.Sie können auch versuchen, dies auf der CodeGolf SE-Website zu veröffentlichen, aber hier ist meine alternative Python-Version (nur für Kick-Challenge):
Angenommen, Sie
input.txt
enthalten Ihre Daten und sind mit 32 Zeichen pro Zeile formatiert.Dies verwendet das Python 3-
struct
Paket und das Schreiben / Lesen von stdin / out. (In Python 2 wäre es kürzer gewesen).quelle