2017-06-28 5 views
1

J'ai un dossier plein de très gros fichiers qui ont besoin d'être inversé par une puissance de 4. Donc, essentiellement, je dois lire les fichiers comme un binaire, ajuster la séquence de bits, puis écrire un nouveau binaire fichier avec les bits ajustés.Python - moyen efficace de retourner des octets dans un fichier?

Essentiellement, ce que je suis en train de faire est de lire une chaîne hexagonale hexString qui ressemble à ceci: « 00112233AABBCCDD »

et écrire un fichier qui ressemble à ceci: « 33221100DDCCBBAA »

(c'est à dire que chaque deux caractères est un octet, et j'ai besoin de retourner les octets par une puissance de 4)

Je suis très novice en python et en codage en général, et la façon dont j'effectue actuellement cette tâche est extrêmement inefficace. Mon code ressemble actuellement à ceci:

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 

Le code que je collais ci-dessus avec précision ce que j'accomplit besoin (note, mon code réel a quelques lignes supplémentaires de: « hexString.replace() » pour supprimer les caractères hexadécimaux inutiles - mais j'ai laissé ceux dehors pour rendre le au-dessus plus facile à lire). Mon problème ultime est que cela prend EXTRÊMEMENT longtemps pour exécuter mon code avec des fichiers plus volumineux. Certains de mes fichiers que j'ai besoin de retourner ont une taille de presque 2 Go, et le code allait prendre presque une demi-journée pour compléter un seul fichier. J'ai des dizaines de fichiers dont j'ai besoin pour exécuter cette tâche, de sorte que le calendrier n'est tout simplement pas pratique.

Existe-t-il un moyen plus efficace de retourner les valeurs HEX dans un fichier avec une puissance de 4?

.... pour ce que ça vaut, il y a un outil appelé WinHEX qui peut le faire manuellement, et ne prend qu'une minute au maximum pour retourner le fichier entier .... J'espérais juste automatiser cela avec python Nous n'avons pas eu à utiliser manuellement WinHEX à chaque fois

+0

Alors ... vous voulez changer l'endianess des nombres 32bit? – kay

+1

Donc, vous voulez convertir vos entiers binaires de 4 octets de little-endian à big-endian ou vice-versa? Vous devriez utiliser ['struct'] (https://docs.python.org/3/library/struct.html). –

+0

Copie possible de [python décompresser little endian] (https://stackoverflow.com/questions/12163549/python-unpack-little-endian) –

Répondre

2

Vous voulez convertir vos entiers de 4 octets de little-endian à big-endian, ou vice-versa. Vous pouvez utiliser le module struct pour que:

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

Pouvez-vous expliquer ce que fait le "si non" dans le loup? Je ne vois pas où "d" est défini - donc juste un peu confus à ce sujet. Merci pour l'aide! – occvtech

+0

** sinon d ** est vrai si d est Aucun, c'est-à-dire s'il n'y a plus de données à lire – SEDaradji

2

Voici un petit struct génialité pour vous aider à démarrer:

>>> 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' 

Pour ce faire à pleine vitesse pour une grande entrée, utilisez struct.iter_unpack

+0

Oh, 'iter_unpack' est cool. Je pense que c'est plus rapide que de faire manuellement 'read()' s? –

+0

Je m'apprête à tester struct.iter_unpack sur l'un de mes fichiers de test. Ai-je encore besoin de 'avec open()' en mode 'read binary' avant de déballer les bits, ou existe-t-il un moyen plus direct de décompresser directement à partir des valeurs binaires du fichier? Merci de votre aide! – occvtech

+0

J'ai testé 'iter_unpack', mais cela ne fonctionne pas avec les objets fichiers tamponnés ou non. Donc, vous devriez soit lire le fichier dans son ensemble dans un objet octets, soit faire une boucle manuellement, comme je l'ai montré. Ou est-ce que je fais quelque chose de mal? –