Реализовать разбор двоичного формата данных
Реализовать разбор двоичного формата данных. Данные начинаются с сигнатуры 0x4b 0x49 0x50 0x5d, за которой следует структура A. Порядок байт: от младшего к старшему. Адреса указаны в виде смещений от начала данных. В решении предлагается использовать модуль struct.
Пример 1
Двоичные данные:
(b'KIP]X\x00\xf1\x11&\xe1\xb3\xd8o\xb1>\x02\x00s\x00\x00\x00\xd8=\xfbW\x81\xcdy' b'\xe1\xccu>\x03X\xcf\xcbPU\xee:\x18\x8a!\x14\xc8\xee\xed#C^\xf0\xa2"7\xf8`' b'\xa7\xe17cD\r2\xc9\x82\xa0\xdfU\x9f\x93\xc0\x8b2\xff\xe2\x88& \x82\x8f' b'\xe7?\x1e#Q|\xede\xb4\xf6M\x02\x00\x00\x00\x1b\x00\x02Y\x19\xbf\x05\x00S' b'\x00\x00\x00\x02r\xeb\x1c\xba\x87\xe2\xbf\x1b\x08\x9e>g\x82\t?')
Результат разбора:
{'A1': {'B1': -2380, 'B2': 77, 'B3': [{'C1': -3506048743108714119, 'C2': [203, 80], 'C3': -4029558889594032555, 'C4': 2495821431160696302, 'C5': 63543}, {'C1': 3606614069523621728, 'C2': [201, 130], 'C3': 3642216463925108640, 'C4': 16685698219028046591, 'C5': 7743}], 'B4': -0.599014401435852, 'B5': [35, 81, 124, -19, 101], 'B6': -0.5790682377660803}, 'A2': {'D1': 3777368561, 'D2': -1318070093, 'D3': 62, 'D4': [0.30865558981895447, 0.5371460318565369], 'D5': 15832}, 'A3': -5, 'A4': 87, 'A5': 129, 'A6': -51}
class Types:
int8 = 'b'
int16 = 'h'
int32 = 'i'
int64 = 'q'
uint8 = 'B'
uint16 = 'H'
uint32 = 'I'
uint64 = 'Q'
float = 'f'
double = 'd'
char = 's'
class BinaryReader:
def __init__(self, data, offset, order='<'):
self.data = data
self.offset = offset
self.order = order
def jump_to(self, offset):
reader = BinaryReader(self.data, offset, self.order)
return reader
def read(self, frmt):
data = unpack_from(self.order + frmt, self.data, self.offset)
self.offset += calcsize(frmt)
return data[0]
def read_d(reader):
d1 = reader.read(Types.uint32)
d2 = reader.read(Types.int32)
d3 = reader.read(Types.uint8)
d4_size = reader.read(Types.uint16)
d4_offset = reader.read(Types.uint32)
d4_reader = reader.jump_to(d4_offset)
d4 = b''.join([d4_reader.read(Types.float)
for _ in range(d4_size)]).decode()
d5 = reader.read(Types.int16)
return dict(D1=d1, D2=d2, D3=d3, D4=d4, D5=d5)
def read_c(reader):
c1 = reader.read(Types.int64)
c2 = [reader.read(Types.uint8) for _ in range(2)]
c3 = reader.read(Types.int64)
c4 = reader.read(Types.uint64)
c5 = reader.read(Types.uint16)
return dict(C1=c1, C2=c2, C3=c3, C4=c4, C5=c5)
def read_b(reader):
b1 = reader.read(Types.int16)
b2 = reader.read(Types.uint8)
b3_size = reader.read(Types.uint32)
b3_offset = reader.read(Types.uint16)
b3_reader = reader.jump_to(b3_offset)
b3 = [read_c(b3_reader) for _ in range(b3_size)]
b4 = reader.read(Types.float)
b5_size = reader.read(Types.uint16)
b5_offset = reader.read(Types.uint32)
b5_reader = reader.jump_to(b5_offset)
b5 = [b5_reader.read(Types.uint8) for _ in range(b5_size)]
b6 = reader.read(Types.double)
return dict(B1=b1, B2=b2, B3=b3, B4=b4, B5=b5, B6=b6)
def read_a(reader):
b_offset = reader.read(Types.uint16)
b_reader = reader.jump_to(b_offset)
a1 = read_c(b_reader)
a2 = read_d(reader)
a3 = reader.read(Types.int8)
a4 = reader.read(Types.uint8)
a5 = reader.read(Types.uint8)
a6 = reader.read(Types.int8)
return dict(A1=a1, A2=a2, A3=a3, A4=a4, A5=a5, A6=a6)
def main(data):
return read_a(BinaryReader(data, 4))
Traceback (most recent call last):
File "/home/program.py", line 25, in <module>
result = main(*args)
File "<string>", line 85, in main
File "<string>", line 76, in read_a
File "<string>", line 41, in read_d
TypeError: sequence item 0: expected a bytes-like object, float found ```
В чем ошибка?