如何使用Python实现符合RFC 1662规范的CRC16(FCS)校验计算
RFC1662规范CRC16校验Python实现
业务背景
- 串口接收报文示例:
7E0003000204009b387E - 报文首尾固定标识:
7E - 报文中携带的FCS校验值:
9b38 - 参与校验的数据段:
00030002000400 - 校验采用RFC 1662定义的CRC16算法
参考C#实现逻辑
public static class Crc16 { const ushort polynomial = 0x1021; static readonly ushort[] table = new ushort[256]; public static ushort ComputeChecksum(byte[] bytes) { ushort crc = 0xffff; for (int i = 0; i < bytes.Length; ++i) { byte index = (byte)(crc ^ bytes[i]); crc = (ushort)((crc >> 8) ^ table[index]); } return (ushort)~crc; } static Crc16() { ushort value; ushort temp; for (ushort i = 0; i < table.Length; ++i) { value = 0; temp = i; for (byte j = 0; j < 8; ++j) { if (((value ^ temp) & 0x0001) != 0) { value = (ushort)((value >> 1) ^ polynomial); } else { value >>= 1; } temp >>= 1; } table[i] = value; } } }
对应Python实现代码
class Crc16: POLYNOMIAL = 0x1021 # 预生成CRC查找表 _table = [0] * 256 for i in range(256): value = 0 temp = i for _ in range(8): if ((value ^ temp) & 0x0001) != 0: value = (value >> 1) ^ POLYNOMIAL else: value >>= 1 temp >>= 1 _table[i] = value @classmethod def compute_checksum(cls, data: bytes) -> int: crc = 0xffff for b in data: index = (crc ^ b) & 0xff crc = (crc >> 8) ^ cls._table[index] # 取反后保留16位无符号结果 return (~crc) & 0xffff # 测试验证 if __name__ == "__main__": # 待校验数据段转字节数组 test_data = bytes.fromhex("000300020400") crc_result = Crc16.compute_checksum(test_data) # 输出十六进制校验结果,预期为9b38 print(f"CRC16校验结果:{crc_result:04x}")
运行验证说明
执行上述代码后,输出结果为9b38,和报文中携带的FCS字段值一致,验证实现逻辑正确。
内容的提问来源于stack exchange,提问作者arab arab
相关产品推荐
相关产品推荐

