目录

 一、原链接:

二、前提知识:

1.异或运算:

 2.多项式

 3.除数

 三、计算步骤

1. 展开多项式得到CRC除数

2.在源数据串末尾加0

 3.计算校验和

 4.将数据串与校验和合并

代码:


 一、原链接:

[CRC校验]手算与直观演示_哔哩哔哩_bilibili

二、前提知识:

1.异或运算:

 2.多项式

 3.除数

CRC中用到的除数,正是由多项式的各系数组成:

 三、计算步骤

1. 展开多项式得到CRC除数

 (为避免出错,应该从右往左写)

2.在源数据串末尾加0

0的数量由多项式决定,具体来说,多项式的阶数是几就加几个0

 假如有个数据串为1101011011,就在末尾添加6个0

 此时添加0后的数据串为:

 于是,现在既有了数据串,也有了除数

 下面就可以计算校验和了。

 3.计算校验和

1.将数据串的第一个1与除数左对齐

 2.按位进行异或:相同得0,相异得1

3.将未处理的数据搬下来作为新数据串,然后重复上一个步骤

3.1 将未处理的数据搬下来:

 3.2 将合并后的数据再搬上去

 3.3 让除数(图中第2行)与数据串(图中第1行)的第一个1对齐:

 3.4 按位进行异或操作

 接下来就是重复步骤2和3,不断的进行异或运算,

为方便理解,这里再写一步:

 

 

 

 ...

最终结果:111011

 这个结果就是CRC校验和。

为什么要把校验和的第一个0舍去?

因为规定校验和的长度为除数的长度减1

 4.将数据串与校验和合并

这样就得到了带有CRC校验的数据

代码:

import time

def toAscii_2(str):
    list_ascii = []
    for str in str:
        ascii_10 = ord(str)
        ascii_2 = bin(ascii_10)[2:]
        list_ascii.append(ascii_2)
    return list_ascii

def yiHuo(shuJuChuan_2Andinit_2,chuShu_2):
    try:
        chuShu_2_length = len(chuShu_2)  # 除数长度
        row1 = shuJuChuan_2Andinit_2[:chuShu_2_length]
        yiHuoList = []  # 用来存储一次异或的结果
        for i in range(chuShu_2_length):
            yiHuoList.append(str(int(row1[i]) ^ int(chuShu_2[i])))
        yihuoResult = "".join(yiHuoList)  # 异或结果
        yihuoResult1 = "".join(yiHuoList)  # 去开头的0后的异或结果

        yiHuoResultCombine = yihuoResult1 + shuJuChuan_2Andinit_2[len(yihuoResult):]  # 一次异或后拼接数据串剩余字符
        index_one = yiHuoResultCombine.index("1")  # 找到第一个1的索引
        yiHuoResultCombine = yiHuoResultCombine[index_one:]  # 从第一个1开始截取yiHuoResultCombine
        if len(yiHuoResultCombine)< chuShu_2_length-1:
            yiHuoResultCombine = "0"*((chuShu_2_length-1)-len(yiHuoResultCombine)+1)+yiHuoResultCombine
        else:
            pass
        if len(yiHuoResultCombine) == chuShu_2_length and yiHuoResultCombine[1]=="0":
            return yiHuoResultCombine
        else:
            return yiHuo(yiHuoResultCombine,chuShu_2)
    except:
        return yiHuoResultCombine



if __name__ == '__main__':
    chuShu = "1010111"  # 除数的2进制表示 str
    shuJuChuan = "1101011011000000"  # 数据串的2进制表示 str
    checkSum = yiHuo(shuJuChuan,chuShu)  # 校验和
    print(checkSum)

运行结果:

如有误,请批评指正

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐