2017-06-28 1 views
1

Ich habe einen Ordner voller sehr große Dateien, die mit einer Potenz von 4 Byte gewendet werden müssen. Also im Wesentlichen muss ich die Dateien als Binär lesen, die Reihenfolge der Bits anpassen und dann eine neue Binärdatei schreiben Datei mit den Bits angepasst.Python - Effiziente Möglichkeit, Bytes in einer Datei umzukehren?

Im Grunde, was ich versuche einen Hex-String hexString zu tun ist, lesen, die wie folgt aussieht: „00112233AABBCCDD“

Und eine Datei schreiben, die wie folgt aussieht: „33221100DDCCBBAA“

(dh alle zwei Zeichen ist ein Byte, und ich muss die Bytes mit einer Potenz von 4 umdrehen)

Ich bin sehr neu zu Python und Codierung im Allgemeinen, und die Art und Weise, die ich derzeit diese Aufgabe ausführen ist äußerst ineffizient. Mein Code sieht derzeit wie folgt aus:

import binascii 

with open(myFile, 'rb') as f: 
     content = f.read() 

hexString = str(binascii.hexlify(content)) 

flippedBytes = "" 
inc = 0 

while inc < len(hexString): 
    flippedBytes += file[inc + 6:inc + 8] 
    flippedBytes += file[inc + 4:inc + 6] 
    flippedBytes += file[inc + 2:inc + 4] 
    flippedBytes += file[inc:inc + 2] 
    inc += 8 

..... write the flippedBytes to file, etc 

Der Code, den ich oben genau eingefügt erreicht, was ich brauche (beachten Sie, meine eigentliche Code hat ein paar zusätzliche Zeilen: „hexString.replace()“ unnötige Hex-Zeichen entfernen - aber ich habe diese weggelassen, um das Obenstehende leichter lesbar zu machen). Mein ultimatives Problem ist, dass es EXTREM dauert, meinen Code mit größeren Dateien auszuführen. Einige meiner Dateien, die ich umdrehen muss, sind fast 2 GB groß, und der Code würde fast einen halben Tag benötigen, um eine einzelne Datei zu vervollständigen. Ich habe Dutzende von Dateien, die ich ausführen muss, so dass Zeitrahmen einfach nicht praktikabel ist.

Gibt es eine effizientere Möglichkeit, die HEX-Werte in einer Datei mit einer Potenz von 4 zu spiegeln?

... für das, was es wert ist, gibt es ein Tool namens WinHEX, das kann manuell tun, und dauert nur eine Minute max, um die ganze Datei zu spiegeln .... Ich hatte nur gehofft, dies mit Python zu automatisieren Wir mussten WinHEX nicht jedes Mal manuell verwenden

+0

Also ... willst du die Endlichkeit von 32-Bit-Nummern ändern? – kay

+1

Also möchten Sie Ihre binären 4-Byte-Ganzzahlen von Little-Endian zu Big-Endian oder umgekehrt konvertieren? Sie sollten ['struct'] (https://docs.python.org/3/library/struct.html) verwenden. –

+0

Mögliches Duplikat von [python entpacke Little Endian] (https://stackoverflow.com/questions/12163549/python-unpack-little-endian) –

Antwort

2

Sie möchten Ihre 4-Byte-Ganzzahlen von Little-Endian zu Big-Endian oder umgekehrt konvertieren. Sie können die struct Modul für die Verwendung:

import struct 

with open(myfile, 'rb') as infile, open(myoutput, 'wb') as of: 
    while True: 
     d = infile.read(4) 
     if not d: 
      break 
     le = struct.unpack('<I', d) 
     be = struct.pack('>I', *le) 
     of.write(be) 
+0

Kannst du erklären, was das "wenn nicht d" in der Loup macht? Ich sehe nicht, wo "d" definiert ist - also etwas verwirrt. Danke für die Hilfe! – occvtech

+0

** wenn nicht d ** ist wahr, wenn d keiner ist, dh wenn es keine Daten mehr zu lesen gibt – SEDaradji

2

Hier ist ein kleines struct awesomeness Ihnen den Einstieg:

>>> import struct 
>>> s = b'\x00\x11\x22\x33\xAA\xBB\xCC\xDD' 
>>> a, b = struct.unpack('<II', s) 
>>> s = struct.pack('>II', a, b) 
>>> ''.join([format(x, '02x') for x in s]) 
'33221100ddccbbaa' 

dies für einen großen Eingang mit voller Geschwindigkeit Verwenden Sie dazu struct.iter_unpack

+0

Oh, 'iter_unpack' ist cool. Ich denke, das ist schneller als manuell 'read()' s? –

+0

Ich richte mich aus, um struct.iter_unpack auf einer meiner Testdateien zu testen. Muss ich vor dem Entpacken der Bits noch mit open() 'im' binary'-Modus lesen, oder gibt es einen direkteren Weg, direkt aus den Binärwerten der Datei zu entpacken? Danke für Ihre Hilfe! – occvtech

+0

Ich habe 'iter_unpack' getestet, aber es funktioniert nicht mit gepufferten oder ungepufferten Dateiobjekten. Also müsste man entweder die Datei als Ganzes in ein Byte-Objekt einlesen, oder manuell, wie ich gezeigt habe. Oder mache ich etwas falsch? –

Verwandte Themen