2010-08-04 18 views
4

Ma tâche actuelle est de disséquer les données tcpdump qui comprend des messages P2P et j'ai des problèmes avec les données pièce que j'acquiers et écrire dans un fichier sur ma machine x86. Mon soupçon est que j'ai un problème simple d'endian-avec les octets que j'écris pour classer.Méthode Python pour stocker la liste des octets dans le réseau (big-endian) ordre de byte (little-endian)

J'ai une liste d'octets contenant un morceau de vidéo P2P lu et traité en utilisant le paquet python-pcapy BTW.

bytes = [14, 254, 23, 35, 34, 67, etc... ]

Je cherche un moyen de stocker ces octets, qui est détenu dans une liste dans mon application Python dans un fichier.

Actuellement j'écrire les pièces comme suit:

def writePiece(self, filename, pieceindex, bytes, ipsrc, ipdst, ts): 
    file = open(filename,"ab") 
    # Iterate through bytes writing them to a file if don't have piece already 
    if not self.piecemap[ipdst].has_key(pieceindex): 
     for byte in bytes: 
      file.write('%c' % byte) 
     file.flush() 
     self.procLog.info("Wrote (%d) bytes of piece (%d) to %s" % (len(bytes), pieceindex, filename)) 

    # Remember we have this piece now in case duplicates arrive 
    self.piecemap[ipdst][pieceindex] = True 

    # TODO: Collect stats 
    file.close() 

Comme vous pouvez le voir dans la boucle, j'écris les octets du fichier dans le même ordre que je les processus du fil (c.-à-réseau ou ordre big-endian).

Autant dire, la vidéo qui est la charge utile des morceaux ne je pense que la lecture pas bien dans VLC :-D

je dois les convertir en ordre petit-boutiste, mais ne suis pas sûr de la meilleure façon pour aborder cela en Python.

MISE À JOUR

La solution qui a fonctionné pour moi (écrire des pièces P2P traitement des problèmes de endian appropriée) était:

def writePiece(self, filename, pieceindex, bytes, ipsrc, ipdst, ts): 
    file = open(filename,"r+b") 
    if not self.piecemap[ipdst].has_key(pieceindex): 
     little = struct.pack('<'+'B'*len(bytes), *bytes) 
     # Seek to offset based on piece index 
     file.seek(pieceindex * self.piecesize) 
     file.write(little) 
     file.flush() 
     self.procLog.info("Wrote (%d) bytes of piece (%d) to %s" % (len(bytes), pieceindex, filename)) 

    # Remember we have this piece now in case duplicates arrive 
    self.piecemap[ipdst][pieceindex] = True 

    file.close() 

La clé de la solution a été l'utilisation du module struct Python comme suspecté et en particulier:

little = struct.pack('<'+'B'*len(bytes), *bytes) 

Grâce à ceux qui ont répondu avec des suggestions utiles.

+1

Les octets n'ont pas de type endianity - only qui se composent de plusieurs octets (c.-à-d. 16bit, 32bit etc.) peuvent être big-endian ou little-endian. Par conséquent, actuellement votre question n'a pas de sens ... – adamk

+0

est-ce vraiment toujours vrai si? n'est-il pas possible pour un octet d'avoir le LSB à l'extrémité gauche d'un octet sur un morceau de matériel mais à droite pour un autre morceau de matériel? sûrement, théoriquement on peut avoir un petit octet endian et un gros octet endian? – bph

Répondre

1

Vous pouvez également utiliser un array.array:

from array import array 
f.write(array('B', bytes)) 

au lieu de

f.write(struct.pack('<'+'B'*len(bytes), *bytes)) 

qui, lorsqu'il est tondu un peu est

f.write(struct.pack('B' * len(bytes), *bytes)) 
# the < is redundant; there is NO ENDIANNESS ISSUE 

qui, si len (octets) est « grand "pourrait être mieux comme

f.write(struct.pack('%dB' % len(bytes), *bytes)) 
2

Pour vous épargner un travail que vous voudrez peut-être utiliser un bytearray (Python 2.6 et versions ultérieures):

b = [14, 254, 23, 35] 
f = open("file", 'ab') 
f.write(bytearray(b)) 

Cela fait tout le convertir de vos valeurs 0-255 en octets sans avoir besoin de tout le looping .

Je ne peux pas voir ce que votre problème est autrement sans plus d'informations. Si les données sont vraiment octets, l'endianisme n'est pas un problème, comme d'autres l'ont dit. (Au fait, utiliser bytes et file car les noms de variables ne sont pas bons car ils cachent les noms de domaine du même nom).

+0

Merci pour le conseil, noté. – codeasone

+0

Je suis limité à Python 2.5.4 pour ce projet. Merci pour la perspicacité dans bytearray si Scott. – codeasone