Альтернативы использованию pack_into () при манипулировании списком байтов? - PullRequest
2 голосов
/ 15 июля 2009

Я читаю двоичный файл в список и анализирую двоичные данные. Я использую unpack () для извлечения определенных частей данных как примитивных типов данных, и я хочу отредактировать эти данные и вставить их обратно в исходный список байтов. Использование pack_into () облегчит эту задачу, за исключением того, что я использую Python 2.4, а pack_into () не был представлен до версии 2.5

Кто-нибудь знает хороший способ сериализации данных таким образом, чтобы я мог выполнять практически те же функции, что и pack_into ()?

Ответы [ 2 ]

4 голосов
/ 17 июля 2009

Вы смотрели на модуль bitstring? Он предназначен для упрощения создания, анализа и изменения двоичных данных, чем непосредственное использование модулей struct и array.

Он специально создан для работы на битовом уровне, но также будет работать с байтами. Он также будет работать с Python 2.4.

from bitstring import BitString
s = BitString(filename='somefile')

# replace byte range with new values
# The step of '8' signifies byte rather than bit indicies.
s[10:15:8] = '0x001122'

# Search and replace byte value with two bytes
s.replace('0xcc', '0xddee', bytealigned=True)

# Different interpretations of the data are available through properties
if s[5:7:8].int > 1000:
    s[5:7:8] = 1000

# Use the bytes property to get back to a Python string
open('newfile', 'wb').write(s.bytes)

Базовые данные, хранящиеся в BitString, являются просто array объектом, но с полным набором функций и специальных методов, которые упрощают его модификацию и интерпретацию.

1 голос
/ 15 июля 2009

Вы имеете в виду редактирование данных в буферном объекте?Документация по манипулированию этими данными непосредственно из Python довольно скудна.

Если вы просто хотите редактировать байты в строке, это достаточно просто;struct.pack_into является новым для 2.5, но struct.pack не является:

import struct
s = open("file").read()
ofs = 1024
fmt = "Ih"
size = struct.calcsize(fmt)

before, data, after = s[0:ofs], s[ofs:ofs+size], s[ofs+size:]
values = list(struct.unpack(fmt, data))
values[0] += 5
values[1] /= 2
data = struct.pack(fmt, *values)
s = "".join([before, data, after])
...