69 lines
2.3 KiB
Python
69 lines
2.3 KiB
Python
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
|
||
|
||
|