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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM