#!/usr/bin/env python3 """ CRC16-CCITT Calculator Based on the provided C implementation """ def calculate_crc16(data): """ Calculate CRC16-CCITT Args: data: bytes or bytearray Returns: uint16 CRC value """ crc = 0xFFFF polynomial = 0x1021 for byte in data: crc ^= (byte << 8) for _ in range(8): if crc & 0x8000: crc = (crc << 1) ^ polynomial else: crc <<= 1 crc &= 0xFFFF # Keep it 16-bit return crc & 0xFFFF def main(): print("=" * 60) print("CRC16-CCITT Calculator") print("=" * 60) print("Enter hex string (space-separated or continuous)") print("Example: AA 55 03 09 00 67 00 00 0A 00 00") print("Or: AA5503090067000000A0000") print("Enter 'q' to quit") print("=" * 60) while True: user_input = input("\nHex data: ").strip() if user_input.lower() == 'q': print("Goodbye!") break if not user_input: continue try: # Remove spaces and convert to bytes hex_string = user_input.replace(" ", "").replace("0x", "") # Validate hex string length (must be even) if len(hex_string) % 2 != 0: print(f"Error: Hex string length must be even (got {len(hex_string)})") continue # Convert to bytes data = bytes.fromhex(hex_string) # Calculate CRC crc = calculate_crc16(data) # Display results print(f"\nInput data ({len(data)} bytes):") print(" ".join(f"{b:02X}" for b in data)) print(f"\nCRC16 Result:") print(f" Hex: 0x{crc:04X}") print(f" Dec: {crc}") print(f" Bytes (Big Endian): {crc >> 8:02X} {crc & 0xFF:02X}") print(f" Bytes (Little Endian): {crc & 0xFF:02X} {crc >> 8:02X}") except ValueError as e: print(f"Error: Invalid hex string - {e}") except Exception as e: print(f"Error: {e}") def test_examples(): """Test with known examples from the log""" print("\n" + "=" * 60) print("Testing with examples from log:") print("=" * 60) examples = [ # Frame 1: Speed 10 ("AA 55 03 09 00 67 00 00 0A 00 00", "9E3C", "Full frame (11 bytes)"), ("09 00 67 00 00 0A 00 00", None, "From DataLen (8 bytes)"), ("67 00 00 0A 00 00", None, "From SeqNum (6 bytes)"), # User's original example from protocol doc ("AA 55 03 09 00 01 00 00 32 00 00", "C37B", "User example (11 bytes)"), ] for hex_data, expected_crc, description in examples: data = bytes.fromhex(hex_data.replace(" ", "")) crc = calculate_crc16(data) print(f"\n{description}:") print(f" Data: {hex_data}") print(f" Calculated CRC: 0x{crc:04X}") if expected_crc: print(f" Expected CRC: 0x{expected_crc}") match = (crc == int(expected_crc, 16)) print(f" Match: {'✓ YES' if match else '✗ NO'}") if __name__ == "__main__": # Run tests first test_examples() # Then start interactive mode print("\n") main()