CRC循环原理简述
要理解CRC的运算过程,先要了解模2运算,这是CRC编码中的运算规则。
也就是说,模2运算就是对两个长度相同的二进制数进行异或运算(不进位借位的运算)。
CRC的运算过程核心是模二除法,模2除法具有下列三个性质:
当最后余数的位数小于除数位数时,除法停止。
当被除数的位数小于除数位数时,则商数为0,被除数就是余数。
只要被除数或部分余数的位数与除数一样多,且最高位为1,不管其他位是什么数,皆可商1。
接下来给出一个简单的CRC编码的实例
除数与被除数最高几位(与除数位数相同)做异或,商1。(除数首位必须为1)
余数先去掉首位,若此时余数最高位为1,商1,并对以它为除数继续模2除。
若最高位为0,则商0,重复步骤2。
直到余数位数小于除数位数时,运算结束
在需要加密的数据(图片里的数据桢)后面添加模二取余的余数(FCS、冗余码)得到密文(图片里的传输帧)
解码:
解密过程和加密过程类似,用需要解密的数据对除数做模2除法,如果余数为0,则代码没有检测出错误(有可能发生了错误但刚好余数也为0)
python代码实现CRC检验误码
CRC检验流程:一个数据帧在发送方进行编码得到传输帧,再通过接收端检查(余数为0)说明数据传输无误
误码概述:如果在传输的过程中数据帧m发生变化,经过编码得到的传输帧在接收端检查余数还为0
代码概述:
- 1、定义函数XOR进行模二运算
传入参数str1,str2分别是被除数和除数。
返回分为首位为0和首位为1俩种情况 - 2、定义函数CRC_Encoding进行编码
传入参数分别是数据帧m和除数p
返回传输帧(数据帧+FCS) - 3、定义函数CRC_Decoding进行解码
传入参数传输帧除数p
返回余数与0的布尔值
为什么不直接用python中^运算符呢?
方便后面解码和编码中的模二除法运算,如果被除数首位为0,用0进行补位
def XOR(str1, str2): #实现模2加法
ans = ''
if str1[0] == '0':
return '0', str1[1:]
else:
for i in range(len(str1)):
if (str1[i] == '0' and str2[i] == '0'):
ans = ans + '0'
elif (str1[i] == '1' and str2[i] == '1'):
ans = ans + '0'
else:
ans = ans + '1'
return '1', ans[1:]
def CRC_Encoding(str1,str2): #CRC编码 原字符串加上模二取余(FCS) 传入参数分别是数据帧m和除数p
lenght = len(str2)
str3 = str1 + '0'*(lenght-1)
ans = ''
yus = str3[0:lenght]
for i in range(len(str1)): #模二除法 补位
str4,yus = XOR(yus, str2)
ans = ans+str4
if i == len(str1)-1:
break
else:
yus = yus+str3[i+lenght]
ans = str1 + yus
return ans #返回传输帧 数据帧+余数(FCS)
def CRC_Decoding(str1,str2): #CRC解码
lenght = len(str2)
str3 = str1 + '0'*(lenght-1)
ans = ''
yus = str3[0:lenght]
for i in range(len(str1)):
str4,yus = XOR(yus, str2)
ans = ans+str4
if i == len(str1)-1:
break
else:
yus = yus+str3[i+lenght]
return yus == '0'*len(yus)
根据CRC检验的误码过程,我们可以理解成:
不同的数据帧m1和m2通过相同的除数p进行编码得到传输帧x1和x2,再将x1和x2用p解码得到的余数都为0时误码成立
def main():
i = 11 #可控参数 数据帧的位数
for m1 in range(2**i): #定义数据m1
m1 = (bin(m1)[2:]).zfill(i) #zfill占位补0
print(m1) #定位
for m2 in range(2**(i)):
m2 = (bin(m2)[2:]).zfill(i)
for p in range(2**(i-3)): #定义比特模式p p不能大于被除数m p首位不为0
p = '1' + (bin(p)[2:]).zfill(i-3)
#print('p = {}'.format(p))
x1 = CRC_Encoding(m1,p)
x2 = CRC_Encoding(m2,p)
flag1 = CRC_Decoding(x1,p)
flag2 = CRC_Decoding(x2,p)
if flag1 and flag2 and m1 != m2 and x1 == x2:
print('数据m1:{}\n数据m2:{}\nm1加密数据:{}\nm2加密数据:{}\np:{}\n'.format(m1,m2,x1,x2,p))
main()
由于本人能力有限,在此留下浅薄的想法
无法呈现出CRC检验误码的例子,恳请大佬指教