Python метод для хранения списка байтов в сети (big-endian) порядок байтов в файл (little-endian)
В настоящее время моя задача состоит в том, чтобы проанализировать данные tcpdump, которые включают P2P-сообщения, и у меня возникли проблемы с фрагментарными данными, которые я получаю и записываю в файл на моей машине x86. Я подозреваю, что у меня есть простая проблема с конечностью с байтами, которые я записываю в файл.
У меня есть список байтов, содержащих фрагмент P2P-видео, прочитанного и обработанного с помощью пакета python-pcapy.
bytes = [14, 254, 23, 35, 34, 67, etc... ]
Я ищу способ хранения этих байтов, которые в настоящее время хранятся в списке в моем приложении Python, чтобы файл.
В настоящее время я пишу пьесы следующим образом:
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()
Как вы можете видеть из цикла for, я записываю байты в файл в том же порядке, что и обрабатываю их из провода (т. е. сетевой или Биг-эндианский порядок).
Достаточно сказать, что видео, которое является полезной нагрузкой частей, не воспроизводится хорошо в VLC : - D
Я думаю, что мне нужно преобразовать их в порядок байтов little-endian, но не уверен, что лучший способ подойти к этому в Python.
Обновление
Решение, которое сработало для меня (написание частей P2P, обрабатывающих эндианские проблемы соответствующим образом), было:
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()
Ключом к решению было использование модуля Python struct в качестве подозреваемого и, в частности:
little = struct.pack('<'+'B'*len(bytes), *bytes)
Спасибо тем, кто откликнулся полезными предложениями.
3 ответа:
Можно также использовать массив .массив :
from array import array f.write(array('B', bytes))Вместо
f.write(struct.pack('<'+'B'*len(bytes), *bytes))Который, когда немного прибран, является
f.write(struct.pack('B' * len(bytes), *bytes)) # the < is redundant; there is NO ENDIANNESS ISSUEКоторый, если len (bytes) "большой" , может быть лучше как
f.write(struct.pack('%dB' % len(bytes), *bytes))
Чтобы сэкономить себе немного работы, вы могли бы использовать
bytearray(Python 2.6 и более поздние версии):b = [14, 254, 23, 35] f = open("file", 'ab') f.write(bytearray(b))Это делает все преобразование ваших 0-255 значений в байты без необходимости всех циклов.
Я не могу понять, в чем заключается ваша проблема без дополнительной информации. Если данные действительно являются байтовыми, то endianness не является проблемой, как говорили другие.
(Кстати, использование
bytesиfileв качестве имен переменных не очень хорошо, так как они скрывают встроенные элементы одного и того же имя).
На этот вопрос можно было ответить ранее в Python File Slurp w/ endian conversion.