异或循环冗余

代码

def fun_crc(datas):
    crc = 0xFF 
    poly = 0x07 
    for i in range(len(datas)):
        for j in range(7, -1, -1):
            if (crc & 0x80) == 0x80: 
                crc = (crc << 1) ^ poly
            else:
                crc = (crc << 1)
            if (datas[i] & 2**j):#值为1的位再异或
                crc ^= poly
    return crc & 0xFF

与一般的CRC8有些不一样。

CRC8-ITU

ITU的全称是国际电信联盟(International Telecommunication Union)。它是一个负责信息通信事务的联合国专门机构,成立于1865年,总部位于瑞士日内瓦。

例程

def cal_crc(datas):
  crc = 0xFF #初始值
  poly = 0x07 # 多项式x^8 + x^2 + x^1 + 1,即0x107,省略了最高位1而得0x07
  for i in range(len(datas)):
      crc = (crc ^ datas[i]) & 0xFF
      for j in range(8, 0, -1):
          if (crc & 0x80) == 0x80: # 判断最高位是否为1,如果是需要异或,否则仅左移
              crc = (crc << 1) ^ poly
          else:
              crc = (crc << 1)
  return crc & 0xFF # 计算后需要进行截取

比较

datas = [0xCB]
start = time.time()	 
print(hex(cal_crc(datas))) 
print("一般循环冗余算法",time.time() - start)
start = time.time()	
print(hex(fun_crc(datas))) 
print("循环冗余算法",time.time() - start)
0x8c
一般循环冗余算法 0.013336658477783203
0x8c
循环冗余算法 0.00408172607421875

计算的结果是一样的,用时还少一点。再用小学三年级上学期的除法算式算一下。

计算

计算CRC8计算过程

不同之处会是多项式除法的一个性质吗,或者是模二运算的性质?

CRC16

开始用的查表法,表里也只有256个元素。用上面两种方式计算的时候要移一个字节,或者直接改成计算16位两个字节。

异或

不一样的是不异或,在计算时处理。可以把(datas[i] & 2**j)的判断放到前面吗?免得异或一次再异或回去。

改进

def fun2_crc(datas):
    crc = 0xFF #初始值
    poly = 0x07 # 多项式x^8 + x^2 + x^1 + 1,即0x107,省略了最高位1而得0x07
    for i in range(len(datas)):
        for j in range(7, -1, -1):
            if (datas[i] & 2**j):#与1异或要翻转
                if (crc & 0x80) == 0x80: 
                    crc = (crc << 1)
                else:
                    crc = (crc << 1) ^ poly
            else:#0或1与0异或不翻转
                if (crc & 0x80) == 0x80: 
                    crc = (crc << 1) ^ poly
                else:
                    crc = (crc << 1)
    return crc & 0xFF # 计算后需要进行截取

测试

datas = [0xCB]
for i in range(1000):
    datas.extend(random.sample(range(255),100))
print(len(datas))
start = time.time()	 
print(hex(cal_crc(datas))) # 输出CRC8校验码
print("一般循环冗余算法",time.time() - start)
start = time.time()	
print(hex(fun_crc(datas))) # 输出CRC8校验码
print("循环冗余算法",time.time() - start)
start = time.time()
print(hex(fun2_crc(datas))) # 输出CRC8校验码
print("改进循环冗余算法",time.time() - start)

把数据增加到十万。打印

 100001
0x27
一般循环冗余算法 0.04993319511413574
0x27
循环冗余算法 6.126452922821045
0x27
改进循环冗余算法 5.69709587097168   

重点

0或1与0异或不翻转,与1异或要翻转。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值