# -*-coding:utf-8-*-

#  多项式 0x8408
POLYNOMIAL = 0x8408
# 初始值为：0xFFFF
INITIAL_VALUE = 0xFFFF


def crc16(dataarray):
    datalength = int(len(dataarray) / 2)
    datalist = [None] * datalength
    index = 0
    try:
        for index in range(datalength):
            item = dataarray[index * 2:index * 2 + 2]
            datalist[index] = int(item, 16)
        res = INITIAL_VALUE
        for data in datalist:
            res = res ^ data
            for index in range(8):
                if res & 0x0001 == 1:
                    res >>= 1
                    res ^= POLYNOMIAL
                else:
                    res >>= 1
        lowbyte = (res & 0xFF00) >> 8
        highbyte = (res & 0x00FF) << 8
        res = lowbyte | highbyte
        return res
    except ValueError as err:
        print(u'第{0}个数据{1}输入有误'.format(index, datalist[index]).encode('utf-8'))
        print(err)


if __name__ == '__main__':
    data_string = '18FF0206E28011700000020A7D001A0702000800000000'  # 16进制输入的数据流
    print('数据 ："{0:s}"对应的CRC16检验码为：{1:04X}'.format(data_string, crc16(data_string)))
    data_string = '18010206E28011700000020A7D001A0701000600000000'  # 16进制输入的数据流
    print('数据 ："{0:s}"对应的CRC16检验码为：{1:04X}'.format(data_string, crc16(data_string)))
    data_string = '06FF010400'  # 16进制输入的数据流
    print('数据 ："{0:s}"对应的CRC16检验码为：{1:04X}'.format(data_string, crc16(data_string)))
