""" Dolphin.py Access your dolphin's state. """ import sys from struct import Struct apps = [ "SubGhz", "Rfid", "Nfc", "Ir", "Ibutton", "Badusb", "U2f", ] dolphin_struct = Struct("B B B B I 7B B I I i L") payload_struct = Struct("7B B I I i L") class Dolphin: def __init__(self): self.header = { "magic": 0, "version": 0, "checksum": 0, "flags": 0, "timestamp": 0, } self.apps_icounter = {app: 0 for app in apps} self.butthurt_limit = 0 self.flags = 0 self.icounter = 0 self.butthurt = 0 self.timestamp = 0 def set(self, *values): self.header = { "magic": values[0], "version": values[1], "checksum": values[2], "flags": values[3], "timestamp": values[4], } self.apps_icounter = dict(zip(apps, values[5:12])) self.butthurt_limit = values[12] self.flags = values[13] self.icounter = values[14] self.butthurt = values[15] self.timestamp = values[16] self.check() return self @classmethod def load(cls, file): """Load a dolphin from a file""" new = Dolphin() with open(file, "rb") as fp: parsed_data = dolphin_struct.unpack(fp.read()) return new.set(*parsed_data) def save(self, file): """Save a dolphin to a file""" self.check() with open(file, "wb") as fp: fp.write(self.pack()) def pack(self): """Pack the dolphin into byte string""" return dolphin_struct.pack( self.header["magic"], self.header["version"], self.compute_checksum(), self.header["flags"], self.header["timestamp"], *self.values, ) def pack_payload(self): """Pack just the payload into a byte string""" return payload_struct.pack(*self.values) @property def values(self): """Return the payload values of the dolphin.""" return [ *self.apps_icounter.values(), self.butthurt_limit, self.flags, self.icounter, self.butthurt, self.timestamp, ] def compute_checksum(self): """Compute the checksum of the payload""" checksum = 0 for byte in self.pack_payload(): checksum += int(byte) return checksum % 128 def check(self): # assert self.icounter == sum(self.apps_icounter.values()) assert self.compute_checksum() == self.header["checksum"] def main(): d = Dolphin.load(sys.argv[1]) # Pretend I played with him. d.icounter += 9999 d.header["checksum"] = d.compute_checksum() d.save(".dolphin.state") main()