""" CRC-ITU Implementation for KKS Badge Protocol Uses CRC-16/X-25 (reflected CRC-CCITT): Polynomial: 0x8408 (reflected 0x1021) Initial value: 0xFFFF Final XOR: 0xFFFF """ from typing import List # --------------------------------------------------------------------------- # Pre-computed CRC lookup table (256 entries, reflected polynomial 0x8408) # --------------------------------------------------------------------------- _CRC_TABLE: List[int] = [] def _generate_crc_table() -> List[int]: """Generate the CRC-16/X-25 lookup table for reflected polynomial 0x8408.""" table: List[int] = [] for i in range(256): crc = i for _ in range(8): if crc & 1: crc = (crc >> 1) ^ 0x8408 else: crc >>= 1 table.append(crc) return table _CRC_TABLE = _generate_crc_table() def crc_itu(data: bytes) -> int: """ Compute the CRC-ITU checksum for the given data. Uses the CRC-16/X-25 algorithm (reflected CRC-CCITT with final XOR). For a KKS protocol packet this should be the bytes from (and including) the packet-length field through the serial-number field. Parameters ---------- data : bytes The data to compute the CRC over. Returns ------- int 16-bit CRC value. """ crc: int = 0xFFFF for byte in data: crc = (crc >> 8) ^ _CRC_TABLE[(crc ^ byte) & 0xFF] return crc ^ 0xFFFF def verify_crc(data: bytes, expected_crc: int) -> bool: """ Verify that *data* produces the *expected_crc*. Parameters ---------- data : bytes The data slice to check (same range used when computing the CRC). expected_crc : int The 16-bit CRC value to compare against. Returns ------- bool ``True`` if the computed CRC matches *expected_crc*. """ return crc_itu(data) == (expected_crc & 0xFFFF)