2016-04-02 7 views
1

In einer Klasse, in der ich bin, sind wir einem einfachen Mips-Simulator zugeordnet. Die Anweisungen, die mein Programm verarbeiten soll, sind in einer Binärdatei angegeben. Ich habe keine Ahnung, wie ich aus dieser Datei etwas brauchbares herausholen kann. Hier ist mein Code:Wie kann ich binäre Daten von einer Datei in lesbare Basis zwei Binär in Python konvertieren?

Also, zuerst habe ich nur die 4 Bytes gedruckt ich gelesen, um zu sehen, was zurückgegeben wurde. Ich hatte gehofft, einfache Bits (nur 1 und 0) zu sehen. Was ich bekam, waren Byte-Strings von dem, was ich gelesen habe. Also habe ich versucht zu googeln, um herauszufinden, was ich dagegen tun kann. So fand ich, dass ich Struct verwenden konnte, um diese Byte-Zeichenfolgen in ganze Zahlen zu konvertieren. Das gibt sie in einem Format wie (4294967295,) aus.

Das ist immer noch ärgerlich, weil ich das trimmen muss, um es zu einer brauchbaren Ganzzahl zu machen, sogar noch muss ich es in Bits umwandeln (Basis 2). Es ist nett, dass ich die Bytes mit struct entweder als vorzeichenbehaftet oder als vorzeichenlos lesen kann, weil die Hälfte der Eingabe der Eingabedatei 32-Bit-Nummern mit Vorzeichen sind.

All dies scheint viel komplizierter als es sein sollte, nur die Bits aus einer Binärdatei zu bekommen. Gibt es einen einfacheren Weg dies zu tun? Kannst du es auch jemandem erklären, der mit esoterischem Python-Code nicht sehr vertraut ist und der für Binärdaten neu ist?

Mein übergeordnetes Ziel ist es, gerade 32 Bit aus jedem gelesenen 4 Byte zu bekommen. Der Anfang der Datei ist eine Liste von Mips-Opcodes. Also muss ich in der Lage sein, bestimmte Teile dieser Zahlen zu sehen, wie die ersten 5 Bits, dann die nächsten 6, oder so weiter. Das Ende der Datei enthält vorzeichenbehaftete Ganzzahlwerte mit 32 Bit. Die beiden Dateihälften sind durch einen Opcode getrennt.

Vielen Dank für jede Hilfe, die Sie mir geben können. Es macht mich verrückt, dass ich durch Suchen keine direkten Antworten finden kann. Wenn Sie die Binärdatei sehen wollen, sagen Sie mir, wo und ich werde es veröffentlichen.

+0

Möchten Sie nur die Bits eines Wertes visualisieren (https://stackoverflow.com/questions/18111488/convert-integert-to-binary-in-python-and-compare-the-bits), oder möchten Sie sie in [integer] (https: // stackoverflow.com/questions/30971079/How-Do-ich-Convert-ein-Integer-zu-einer-Liste-von-Bits-in-Python) Formular für weitere Manipulation? – Reti43

+0

Ich muss sie als Bits lesen, denke ich. Weil ich spezifische Längen von jedem 32-Bit-Wert benötige. Wie ich sehen muss, was die ersten 6 Bits sind, dann die nächsten 5 usw. Ich brauche also die Werte in geraden Bits, denke ich. Es sei denn, es gibt einen besseren Weg, aber meines Wissens ist dies der einzige Weg, wie ich mit den Daten arbeiten kann. – Jacob

+0

Es gibt ein paar Möglichkeiten, dies zu tun. Sehen Sie sich die obigen Links in meinem Kommentar an. Ich schlage vor, dass Sie in der Frage auch genau angeben, was Ihr Ziel ist, andernfalls können wir keine besseren Ansätze vorschlagen als die Lösung, die Sie in der Frage implementieren möchten. – Reti43

Antwort

1

Beachten Sie, dass normale Python ganzen Zahlen haben keine feste Bitbreite: sie sind so groß, wie sie sein müssen. Dies kann ärgerlich sein, wenn Sie vorzeichenbehaftete Ganzzahlen in Bitfolgen konvertieren möchten. Ich empfehle, dass Sie mit dem, was Sie gerade tun: Umwandlung von Blöcken von 4 Bytes unsigned integer

n = struct.unpack('>I', read_bytes)[0] 

und anschließend entweder format(n, '032b') oder '{0:032b}'.format(n) mit, dass String in ein Bit zu konvertieren, wenn Sie die Bits drucken möchten .

Für den Zugriff auf oder die Bits in einer ganzen Zahl zu ändern, sollten Sie mit String-Konvertierung nicht belästigen, stattdessen sollten Sie Pythons bitweise Operatoren verwenden, &, |, ^, <<, >>, ~. ZB (n >> 7) & 1 gibt Ihnen Bit 7 von n.

Weitere Informationen zu diesen Operatoren finden Sie unter Unary arithmetic and bitwise operations und den folgenden Abschnitten in den Python-Dokumenten.

+0

Also was ist da? Was ich von struct zurückbekomme ist "(2370044120,)" für eine Zahl. Kann ich das gerade zum Format weitergeben? Wie funktionieren die bitweisen Operatoren von python? >> ist eine Verschiebung richtig? Was macht die & 1? Können die bitweisen Operatoren an dem arbeiten, was von struct zurückgegeben wird? – Jacob

+0

Tut mir leid, @Jacob, ich habe vergessen, dass 'struct.unpack' immer ein Tupel zurückgibt. Ich habe meinen Code so korrigiert, dass 'n' nun eine Python-Ganzzahl ist. Und es ist garantiert eine vorzeichenlose 32-Bit-Nummer nach der Formatspezifikation ">> I". –

+0

@Jacob: Ja, '>>' ist eine Rechtsverschiebung, '&' ist bitweises UND, also 'c = a & b' führt die UND-Operation an den entsprechenden Bits der ganzen Zahlen' a' und 'b' durch Ergebnisse in die entsprechenden Bits von "c". Daher wird "n & 1" zu dem niedrigstwertigen Bit von "n" ausgewertet. Die Python-bitweisen Operatoren funktionieren sehr ähnlich wie in C und vielen anderen Sprachen (abgesehen von der Tatsache, dass Python-Integer keine feste Bitbreite haben); Ich dachte, du wärst mit bitweisen Operatoren vertraut, wenn du einen Disassembler erstellst. :) –

0

Auf diese Weise können Sie auf jedes einzelne Bit in der Datei zugreifen.

"".join(format(i, "08b") for i in byte_string) 

Zum Beispiel:

>>> "".join(format(i, "08b") for i in b"\x23\x54a") 
'001000110101010001100001' 
+0

'bin' gibt Ihnen keine Kontrolle über die Länge der resultierenden Zeichenfolge, und es wird '' 0b'' vorangestellt, die Sie normalerweise abschneiden möchten, wie es Ihr Code tut. Die "Format" -Funktion oder -Methode ist in beiden Fällen überlegen. ZB 'format (n, '032b')' –

+0

Ich habe das in anderen Fragen gepostet. Der einzige Grund, warum ich zögere, es zu benutzen, ist, dass ich nicht weiß, wie es funktioniert. So fügt Join alles hinzu, was in der leeren Zeichenfolge enthalten ist. bin (i) wandelt eine Zahl in eine binäre Zahl um, sodass [2:] das 0b-Präfix entfernt wird? Ich fühle mich, als ob das gerade genug ist, aber warum ist das für mich in b "\ x23 \ x53a" daneben? Was macht eine for-Schleife neben der Bin-Funktion? Wie läuft die Schleife durch? Jedes Byte? – Jacob

+0

@ PM2Ring Danke. Ich habe es in "08b" geändert, da jedes Byte 8 Bits ist, müssen Sie nicht jedes Mal 4 Bytes in int konvertieren. – Bharel