CRC校验怎么算?

IPC摄像机 2022-11-24 10:52:40 936

据说刚过去的高考数学很难,小编当年上学时挺喜欢数学的,最近特意复习了一下CRC校验的计算过程。

CRC是众多校验方式中的一种,校验的目的是为了检测数据的正确性。在详细介绍CRC计算之前,我们先来看两个常见的较为简单点的校验:串口通信中的奇偶校验和身份证号码中的MOD 11-2校验。

先看奇偶校验,假设要发送8位数据10110101,奇校验是再加一位校验位,让这9位数据中的1的个数为奇数。

10110101->101101010 奇校验

偶校验是让这9位数据中1的个数为偶数。

10110101->101101011 偶校验

接收方收到数据后计算其奇偶性,如果不对,则说明数据传输中发生了错误。

奇偶校验优点是使用简单,缺点是检错率有限,只有奇数个数据位发生变化的错误能检测到,偶数个数据位变化的错误它检测不了。

最近拿着身份证去核酸检测的次数太多了,让我对身份证号码的组成产生了兴趣,尤其好奇的是为什么有的身份号号码最后一位是X。身份证号码总共18位,包括17位数字码和1位校验码。

1) 1-6位是地址码,表示编码对象所在县。

2) 7-14位是出生日期码,表示编码对象出生的年、月、日。

3) 15-17位是顺序码,表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男 性,偶数分配给女 性。

4) 校验码,用来检验身份证号码是否正确,采用MOD 11-2校验码系统。

校验的公式如下:

简单来说它的校验规则是:连校验码一起,由从右到左逐位乘以2的n次方取模11并求和,对11的余数必须为1。

以一个身份证号码11010519491231002X为例,

校验码计算如下:

1) 将前面的身份证号码17位数分别乘以不同的系数。从左到右的系数分别为:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2

2) 将这17位数字和对应的系数各自相乘的结果相加7+9+0+5+0+20+2+9+24+27+7+18+30+5+0+0+4=167;

3) 用加出来的和167除以11,余数是2;

4) 余数2对应校验码是X;

看完上述计算方法之后,大家可以用自己的身份证号码试试。

该校验算法据说可以:

1) 如果某一位填错了,则校验算法可以检测出来。

2) 如果身份证号的相邻2位填反了,则校验算法可以检测出来。

这也是为什么要除以11而不是10的原因,其背后的数据理论推理已经超出了我的能力范畴,这里不再介绍了。

上面的两种校验和CRC校验没有什么关系,只是为了让大家对校验先有个感性的认识,下面来正式介绍CRC。

我在网上找了两个计算CRC的软件,输入同样的数据,选择同样的算法,得到的结果一样,

这两个软件的对应关系如下:

把CRC Calculator Info 中的这几个参数弄明白,CRC的过程你也就清楚了

Name:算法的名称,比如对于16bit的CRC来说就有好多个名字,也就是虽然都是16 bit CRC,但是计算方式也有好多种。

Width:指的CRC校验值的长度,通常有8bit,16bit,24bit,32bit等。

Poly:是多项式的值,以上面图中的CRC-8:x8+x2+x+1为例,它表示二进制为100000111,去掉最高位的1,十六进制表示就是0x07

Init:Init 的位数和Poly的位数相同,它的值为全0或者全F,当全为0时,在算法开始前对数据(这个数据是根据RefIn的值得到的)后面补上CRC位数个0后就可以进行后续计算了。当全为1时,表示在算法开始前对数据的前CRC位数(高位)先和对应位数个1进行异或(即:前CRC位数的值按位取反),再在后面补上CRC位数个0,才进行后续计算。

RefIn和Refout:它们要么全为False,要么全为True。

RefIn为False表示,输入的原始数据的每个字节的第7位作为最高有效位,第0位作为最低有效位,即正常计算即可

当RefIn为True时,输入的原始数据的每个字节需要做个逆序的处理,注意:针对的每个字节,而不是整个数据,以一个4字节的原始数据为例:

当Refout为False时,输出不做处理,当Refout为True,需要对输出数据做一次整个数据的逆序处理,注意:这里做的逆序和RefIn不同,它不是按字节逆序,而是整个逆序,以CRC-32为例来说明,最后的数据为32位,当Refout为True时,翻转如下:

XorOut:表示根据上面参数计算完后,和这个数再进行一次异或。

下面分析一下上面的结果0x79的由来:

1) 0x13 对应二进制为00010011

2) 由于RefIn为False,所以0x13不做处理还是00010011

3) 因为Init为0x00,00010011后面加8个0即可,输入数据变为0001001100000000

4) 多项式为x8+x2+x+1 对应二进制100000111,将上述0001001100000000 除以该多项式对应的100000111

整个计算过程如下:

最后得到余数:01111001

5) 由于RefOuT为False,所以余数不变,还为01111001

6) 由于Xorout为0,表示不用再取反,所以最终的结果就是01111001,即十六进制0x79

算一个不过瘾,我们再来计算一个

这一次和上面唯一的不同是将初始值由原来的0x00换为了0xFF,这个例子就是给大家演示初始值到底什么意思.

下面分析一下上面的结果0x79的由来:

1) 0x13 对应二进制为00010011

2) 由于RefIn为False,所以0x13不做处理还是00010011

3) 因为Init为0xFF,00010011的高8位要先与0xFF异或,输入数据变为11101100,后面再加入8个0,变为 1110110000000000

4) 多项式为x8+x2+x+1 对应二进制100000111,将上述1110110000000000 除以该多项式对应的100000111,最后得到余数:10001010

5) 由于RefOuT为False,所以余数不变,还为10001010

6) 由于Xorout为0,表示不用再取反,所以最终的结果就是10001010,即十六进制0x8A

这个例子演示了初始值的含义,我们再看最后一个例子,这个例子演示了RefIn和RefOut为True的具体含义

1) 0x13 对应二进制为00010011

2) 由于RefIn为True,所以0x13需要逆序一下得到11001000

3) 因为Init为0x00,所以11001000后面直接添加4个0即可,得到110010000000

4) 多项式为x4+x+1 对应二进制10011,将上述110010000000 除以10011,最后得到余数:0010

5) 由于RefOuT为True,所以余数要逆序变为0100

6) 由于Xorout为0,表示不用再取反,所以最终的结果就是0100

本文转载自公众号玩点嵌入式,版权归原作者所有,不代表本站观点,如有侵权请与本站联系,本站将第一时间删除

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 点赞 收藏 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
IPC摄像机
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区