python 两种crc16方法

# -*- coding: utf-8 -*-
#! /usr/bin/env python3
import crcmod.predefined

class crc16:
    def __init__(self):
        pass

    def crc16Modbus(self, bytes_data, start_pos, stop_pos, invert=False):
        a = 0xFFFF
        b = 0xA001
        for i in range(start_pos, stop_pos):
            a ^= bytes_data[i]
            for j in range(8):
                last = a % 2
                a >>= 1
                if last == 1:
                    a ^= b
        return (a << 8 & 0xff00) | a >> 8 if invert == False else a
    
    def crc16Modbus2(self, bytes_data, start_pos, stop_pos, invert=False):
        data = bytes_data[start_pos:stop_pos]
        modus_crc_func = crcmod.predefined.mkCrcFun('modbus')
        res = modus_crc_func(data)
        return (res << 8 & 0xff00) | res >> 8 if invert == False else res
    
    def crc16Xmodem(self, bytes_data, start_pos, stop_pos, invert=False):
        wcrc = 0
        for i in range(start_pos, stop_pos):
            data = bytes_data[i]
            for j in range(8):
                treat = data & 0x80
                data <<= 1
                bcrc = (wcrc >> 8) & 0x80
                wcrc <<= 1
                wcrc = wcrc & 0xffff
                if (treat != bcrc):
                    wcrc ^= 0x1021
        return wcrc if invert == False else (wcrc << 8 & 0xff00) | wcrc >> 8

    def crc16Xmodem2(self, bytes_data, start_pos, stop_pos, invert=False):
        data = bytes_data[start_pos:stop_pos]
        xmodem_crc_func = crcmod.predefined.mkCrcFun('xmodem')
        res = xmodem_crc_func(data)
        return res if invert == False else (res << 8 & 0xff00) | res >> 8

# debug type:   singel file 
# file  name:   mycrc16.py
# file  version:    v0.0
# debug time:   2020.8.26
if __name__ == '__main__':
    crc16_test = crc16()
    print(hex(crc16_test.crc16Modbus(bytes('123456789', encoding='utf8'), 0, 9)))
    print(hex(crc16_test.crc16Modbus2(bytes('123456789', encoding='utf8'), 0, 9)))
    print(hex(crc16_test.crc16Xmodem(bytes('123456789', encoding='utf8'), 0, 9)))
    print(hex(crc16_test.crc16Xmodem2(bytes('123456789', encoding='utf8'), 0, 9)))

'''
注意:
    参数说明
    入参:bytes_data 待校验字节串数据,
           start_pos 校验数据起始位置
           stop_pos  校验数据结束位置
           invert=False 校验结果默认低字节在前,如果invert=True则高字节在前
    出参:
        输出2个字节的校验结果
        
    crc16Modbus是自己实现, crc16Modbus2是调用库实现;
    crc16Xmodem2是自己实现, crc16Xmodem2是调用库实现;
'''
 

 

猜你喜欢

转载自blog.csdn.net/qq_34473570/article/details/108370358