"""CRC helpers recovered from ``communication_center/utils/crc16.dart`` / ``crc32.dart``. See ``docs/RE_DART_FINDINGS.md`` §6. * CRC16 = **CRC-16/MODBUS** (init ``0xFFFF``, reflected poly ``0xA001`` — the disassembly shows the literal constant ``40961``). * The app's ``Crc16::calculate`` returns the CRC with **hi/lo bytes swapped**, rendered as a **4 lowercase hex digits** string. * CRC32 (zlib/IEEE) is used for the JSON envelope integrity check. """ from __future__ import annotations import zlib CRC16_INIT = 0xFFFF CRC16_POLY = 0xA001 # reflected 0x8005 (CRC-16/MODBUS) def crc16_modbus(data: bytes) -> int: """CRC-16/MODBUS over *data* (init 0xFFFF, reflected poly 0xA001).""" crc = CRC16_INIT for byte in data: crc ^= byte for _ in range(8): if crc & 1: crc = (crc >> 1) ^ CRC16_POLY else: crc >>= 1 return crc & 0xFFFF def crc16_hex_string(data: bytes) -> str: """The app's ``Crc16::calculate`` equivalent. CRC-16/MODBUS, hi/lo bytes swapped, 4 lowercase hex digits, e.g. ``crc16_modbus(b"123456789") == 0x4B37`` -> swapped ``0x374B`` -> ``"374b"``. """ crc = crc16_modbus(data) swapped = ((crc & 0xFF) << 8) | (crc >> 8) return f"{swapped:04x}" def crc32(data: bytes) -> int: """CRC-32 (IEEE/zlib) — envelope integrity check.""" return zlib.crc32(data) & 0xFFFFFFFF def int16_to_le_bytes(value: int) -> bytes: """``utils.int16ToBytes`` — little-endian 16-bit.""" return (value & 0xFFFF).to_bytes(2, "little") def le_bytes_to_int16(data: bytes) -> int: """``utils.bytesToInt16`` — little-endian 16-bit.""" return int.from_bytes(data[:2], "little")