I'm attempting to take a binary data file exported from a program I'm using, hexlify it using the binascii module, and retrieve the data that I need so I can eventually output that data in a Qt GUI. So far this is what I've got:
import binascii, functools, struct
from pathlib import Path
def read_value(dataset, start, length, encoding):
unhex = binascii.unhexlify(dataset[start * 2:(start + length) * 2])
unpack = struct.unpack(encoding, unhex)
data = functools.reduce(lambda result, decrypted: result * 10 + decrypted, unpack)
return data
class Inventory:
def __init__(self, dataset, category):
self.dataset = dataset
self.category = category
def get_data(self):
if self.category == 'collectibles':
data = self.dataset[0x55060:0x56448]
return data
class Item:
def __init__(self, data, offset):
self.item_id = read_value(data, offset + 0x0, 0x2, '<H')
self.index = read_value(data, offset + 0x2, 0x2, '<H')
self.category = read_value(data, offset + 0x4, 0x1, '<B')
self.amount = read_value(data, offset + 0xC, 0x2, '<H')
self.status = read_value(data, offset + 0xE, 0x2, '<H')
the_file = Path('../file.sav').read_bytes()
the_dataset = binascii.hexlify(the_file)
the_collectibles = Inventory(the_dataset, 'collectibles').get_data()
the_items = [Item(the_collectibles, 0x0), Item(the_collectibles, 0x10)]
print(the_items[0].__dict__)
print(the_items[1].__dict__)
However, I'm getting data that I know shouldn't be there...
Using the above code, I expect the output data at the specified offsets between 0x55060 to 0x56448 to be:
{'item_id': 2002, 'index': 0, 'category': 3, 'amount': 99, 'status': 1}
{'item_id': 2059, 'index': 1, 'category': 3, 'amount': 45, 'status': 1}
However, I get the following numbers that definitely shouldn't exist at those positions:
{'item_id': 65535, 'index': 45928, 'category': 10, 'amount': 65150, 'status': 4614}
{'item_id': 65535, 'index': 0, 'category': 181, 'amount': 20489, 'status': 8093}
If I actually do the following, bypassing the classes and slice, and providing absolute values, I get the numbers that I expect:
item_id = read_value(the_dataset, 0x55060, 0x2, '<H')
index = read_value(the_dataset, 0x55062, 0x2, '<H')
category = read_value(the_dataset, 0x55064, 0x1, '<B')
amount = read_value(the_dataset, 0x5506C, 0x2, '<H')
status = read_value(the_dataset, 0x5506E, 0x2, '<H')
It just seems really like that data = self.dataset[0x55060:0x56448] in the Inventory class isn't slicing the data correctly? I'm not sure if I'm doing something wrong, or if there's another module I should be using to slice the data. Or should I be slicing the data at all?
Any advice would be greatly appreciated!