crc 循环冗余校验-python实现

CRC16 python实现

crc16_IBM

def crc16_IBM(data):
    # parameter data :'01 00 00 80 00 00 00 ..... 00 ce c2 b6 c8 33 38 32 35 a1 e6'
    if isinstance(data, str):
        data = data.strip().split(' ')
        crc = 0x0
        for i in range(len(data)):
            crc = ((int(data[i], base=16) & 0xFF) ^ crc)
            for j in range(8):
                if (crc & 0x1) == 1:
                    crc = (crc >> 1) ^ 0xa001
                else:
                    crc >>= 1
        res = hex(crc)[2:]
        if len(res) < 4:
            res = (4 - len(res)) * '0' + res

        return [res[2:], res[:2]]

环境212数据报字符串循环冗余校验

def crc16(text):
    """
    向服务器发送数据报字符串的循环冗余校验
    hj 212-2017 crc16效验
    :param text: 待效验的字符串
    :return: result
    """
    data = bytearray(text, encoding='utf-8')
    crc = 0xffff
    dxs = 0xa001
    for i in range(len(data)):
        hibyte = crc >> 8
        crc = hibyte ^ data[i]
        for j in range(8):
            sbit = crc & 0x0001
            crc = crc >> 1
            if sbit == 1:
                crc ^= dxs
    res = str(hex(crc)[2:]).upper()
    if len(res) < 4:
        res = (4 - len(res)) * '0' + res

    return res

 CRC_modbus :

def crc_modbus(data_list):
    """

    :param data_list: 接收一个存放字符串的列表:['aa','2a','4B']
    :return: a hex int :0x 1234
    """
    crc_data = 0xffff
    for data in data_list:
        # 把第一个8位二进制数据(通信信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器。
        crc_data_tmp1 = ((crc_data & 0x00ff) ^ int(data, 16)) + (0xff00 & crc_data)
        length = 8
        while True:
            # 把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位。
            # 如果移出位为0,重复第3步(再次右移一位);如果移出位为1,CRC寄存器与多项式A001(1010000000000001)进行异或。
            if (crc_data_tmp1 & 0x0001) == 0:
                crc_data_tmp2 = (crc_data_tmp1 >> 1)
                crc_data_tmp1 = crc_data_tmp2
                length -= 1
            else:
                crc_data_tmp2 = ((crc_data_tmp1 >> 1) ^ 0xA001)
                crc_data_tmp1 = crc_data_tmp2
                length -= 1
                pass
            if length == 0:
                break

        # 返回对一个8位数据的crc校验
        crc_data = crc_data_tmp1
    return ((crc_data & 0x00ff) << 8) | ((crc_data & 0xff00) >> 8)

 CRC_modbus (接收hex字符串)

def crc_modbus_string(hex_string):
    """
    :param hex_string: '0103043e449ba65c84'
    :return: int 1234
    """
    def crc_modbus(data_list):
        """
        :param data_list: 接收一个存放字符串的列表:['aa','2a','4B']
        :return: a hex int :0x 1234
        """
        crc_data = 0xffff
        for data in data_list:
            # 把第一个8位二进制数据(通信信息帧的第一个字节)与16位的CRC寄存器的低8位相异或,把结果放于CRC寄存器。
            crc_data_tmp1 = ((crc_data & 0x00ff) ^ int(data, 16)) + (0xff00 & crc_data)
            length = 8
            while True:
                # 把CRC寄存器的内容右移一位(朝低位)用0填补最高位,并检查右移后的移出位。
                # 如果移出位为0,重复第3步(再次右移一位);如果移出位为1,CRC寄存器与多项式A001(1010000000000001)进行异或。
                if (crc_data_tmp1 & 0x0001) == 0:
                    crc_data_tmp2 = (crc_data_tmp1 >> 1)
                    crc_data_tmp1 = crc_data_tmp2
                    length -= 1
                else:
                    crc_data_tmp2 = ((crc_data_tmp1 >> 1) ^ 0xA001)
                    crc_data_tmp1 = crc_data_tmp2
                    length -= 1
                    pass
                if length == 0:
                    break

            # 返回对一个8位数据的crc校验
            crc_data = crc_data_tmp1
        return ((crc_data & 0x00ff) << 8) | ((crc_data & 0xff00) >> 8)
    list_temp = []
    for i in range(0, len(hex_string), 2):
        list_temp.append(hex_string[i:i + 2])
    res = crc_modbus(list_temp)
    result = hex(res)[2:]
    if len(result) < 4:
        result = (4 - len(result)) * '0' + result
return result

 

posted @ 2021-11-22 16:08  Orientation  阅读(1072)  评论(0编辑  收藏  举报