class crc16: """ CRC16校验函数 """ @staticmethod def cal(data_bytes): """ 计算CRC16校验值(不包含最后两个字节的CRC) 参数: data_bytes: 要计算CRC16的字节数据,可以是bytes、bytearray或整数列表 返回: int: 计算得到的CRC16校验值 """ PRESET_VALUE = 0xFFFF POLYNOMIAL = 0x8408 # 初始化CRC值 crc_value = PRESET_VALUE length = len(data_bytes) # 处理每个字节 for i in range(length): # 获取当前字节(确保是0-255范围内的整数) current_byte = data_bytes[i] & 0xFF # 与当前CRC值异或 crc_value ^= current_byte # 处理每个位 for j in range(8): # 检查最低位 if crc_value & 0x0001: # 最低位为1,右移后与多项式异或 crc_value = (crc_value >> 1) ^ POLYNOMIAL else: # 最低位为0,仅右移 crc_value = crc_value >> 1 # 确保crc_value是16位无符号整数 crc_value &= 0xFFFF return crc_value @staticmethod def verify(data_bytes): """ 验证数据后两位的CRC MSB和LSB是否正确 参数: data_bytes: 要验证CRC16的字节数据,可以是bytes、bytearray或整数列表 返回: bool: True表示CRC验证通过,False表示验证失败 """ if len(data_bytes) < 2: raise ValueError("数据长度至少需要2字节以包含CRC校验值") # 提取数据部分(除去最后两个CRC字节) data_part = data_bytes[:-2] # 提取接收到的CRC值(LSB在前,MSB在后) received_crc_lsb = data_bytes[-2] received_crc_msb = data_bytes[-1] received_crc = (received_crc_msb << 8) | received_crc_lsb # 计算数据部分的CRC值 calculated_crc = crc16.cal(data_part) # 比较计算得到的CRC值和接收到的CRC值 return calculated_crc == received_crc