from typing import Iterable, List from .constants import CHECKSUM_LENGTH_WORDS, CUSTOMIZATION_STRING def _polymod(values: Iterable[int]) -> int: GEN = ( 0xE0E040, 0x1C1C080, 0x3838100, 0x7070200, 0xE0E0009, 0x1C0C2412, 0x38086C24, 0x3090FC48, 0x21B1F890, 0x3F3F120, ) chk = 1 for v in values: b = chk >> 20 chk = (chk & 0xFFFFF) << 10 ^ v for i in range(10): chk ^= GEN[i] if ((b >> i) & 1) else 0 return chk def create_checksum(data: Iterable[int]) -> List[int]: values = list(CUSTOMIZATION_STRING) + list(data) + [0] * CHECKSUM_LENGTH_WORDS polymod = _polymod(values) ^ 1 return [(polymod >> 10 * i) & 1023 for i in reversed(range(CHECKSUM_LENGTH_WORDS))] def verify_checksum(data: Iterable[int]) -> bool: return _polymod(list(CUSTOMIZATION_STRING) + list(data)) == 1