循环冗余校验码原理(CRC码)

吴押狱
• 阅读 2301

循环冗余校验码(Cyclic Redundancy Check, CRC)的基本思想是发送方和接收方约定一个除数,被除数是由信息位(n)和校验位(k)组成,最终除法的余数要等于 0

原理

假设数据为 10101011,生成多项式为 10011,求 CRC 码?

多项式就是双方约定的除数 10011

  • 最高位次幂为 4
  • CRC 码位数由信息位和校验位组成:8 + 4 = 12

由于 CRC 码是 12 位,目前数据为 10101011 只有 8 位,需要左移 4 位(低位补 0),得到 101010110000

对移位后的数据进行模2除,产生余数:

  • 被除数最高位为 11,为 00
  • 剩余位数进行异或运算
  • 最终余数的位数应该比除数的位数少一位

模2除用竖式计算,算出最后的余数为 1010

  • 101010110000/10011

    • 10101/10011 = 1 ... 0110
    • 01100/10011 = 0 ... 1100
    • 11001/10011 = 1 ... 1010
    • 10101/10011 = 1 ... 0110
    • 01100/10011 = 0 ... 1100
    • 11000/10011 = 1 ... 1011
    • 10110/10011 = 1 ... 0101
    • 01010/10011 = 0 ... 1010

余数 1010 就是 CRC 码的校验位,加上信息位组合成最终的 CRC 码: 101010111010

10101011101010011 相除,最终的余数一定是 0000

检错和纠错

发送的 CRC 码记为:C12C11C10C9C8C7C6C5C4C3C2C1

C12C11C10C9C8C7C6C5C4C3C2C1
101010111010

一位出错(纠错)

C12C11C10C9C8C7C6C5C4C3C2C1
101010111010
C4出错101010110010

101010110010代入模2除,得到余数 0100,对应十进制 4,也就是说 C4 处出错了

一位出错(不能纠错)

上面的例子,校验位是 4 位,可以表示 16 种状态,实际的 CRC 码只有 12 位,所以有纠错能力。

如果校验位是 3 位,可以表示 8 种状态,实际的 CRC 码有 9 位,这种情况下就没办法实现纠错了。

假如说现在求得的余数是 010 转换为十进制是 2,能否说明第 2 位出错了呢?

看下面表,010 对应的出错位是 29,也就是说当第二位或者第九位出错了,余数是一样的,这就导致了我们根据 010 没判断出错位了。

接受余数出错位
101001001000
1010010000011
1010010110102
1010011010113
1010000011004
1010110011015
1011010011106
1000010011117
1110010010018
0010010010109

所以要使 CRC 码有纠错能力,必须满足:2^k >= n + k + 1

  • n + k 表示错误的状态的数量
  • 1 表示的正确的状态

不过在实际的应用,CRC 码只用于检错,比如几千个bit+几个校验位

总结

  1. 确定 CRC 码位数
  2. 移位,低位补 0
  3. 模2除求余数,余数是校验位
  4. CRC码 = 信息位 + 校验位

如果要有纠错能力,需要满足:2^k >= n + k + 1

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
4年前
CRC32用途及写法
CRC32今天在看rocketmq源码时,看到CRC32,就记录下来以供学习。主要用途: 在远距离数据通信中,为确保高效而无差错地传送数据,必须对数据进行校验即差错控制。循环冗余校验CRC(CyclicRedundancyCheck/Code)是对一个传送数据块进行校验,是一种高效的差错控制方法。if(!checksum(c
Wesley13 Wesley13
4年前
PIC中档单片机汇编指令详解(5)
位操作指令详述BCF数据寄存器指定位清0语法形式:BCFf,b操作数:f为数据寄存器的低7位地址(0x00~0x7F)B为数据位编号(0~7)执行时间:一个指令周期执行过程:使数据寄存器f的的b位清0状态标志影响:无说明:该指令可对任何数据寄存器的任意一个位置清0,常用于标志位的设定和清除,或者把某一管脚置成低电平。指
Wesley13 Wesley13
4年前
VBox 启动虚拟机失败
在Vbox(5.0.8版本)启动Ubuntu的虚拟机时,遇到错误信息:NtCreateFile(\\Device\\VBoxDrvStub)failed:0xc000000034STATUS\_OBJECT\_NAME\_NOT\_FOUND(0retries) (rc101)Makesurethekern
Wesley13 Wesley13
4年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
4年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
4年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0