CRC的全称为Cyclic Redundancy Check,中文名称为循环冗余校验。它是一类重要的线性分组码,编码和解码方法简单,检错和纠错能力强,在通信领域广泛地用于实现差错控制。
利用CRC进行检错的过程可简单描述为:在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的r位监督码(CRC码),附在原始信息后边,构成一个新的二进制码序列数共k+r位,然后发送出去。在接收设备,根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。这个规则,在差错控制理论中称为“生成多项式”。
最常用的CRC校验码是16位(2字节)的。我们在这里选定使用CRC-ITU,其多项式为:
G(X) = 1+X5+X12+X16
CRC算法既可以用硬件实现,也可以软件实现。用硬件实现的移位反馈寄存器的逻辑图如附录A.1所示。编码、解码前将各寄存器初始化为"1",信息位随着时钟移入。当信息位全部输入后,从寄存器组输出CRC结果。
图1 用硬件实现的移位反馈寄存器的逻辑图
上述硬件移位逻辑可通过软件模拟,其计算方法是:
a) 寄存器组初始化为全"1"(0xFFFF)。
b) 寄存器组与数据字节进行异或运算;
c) 检查最低位,如果最低位为1,把寄存器组向低位移一位并与多项式(0x8408)相异或,如果最低位为0,只把寄存器组向低位移一位,不进行异或运算。
d) 重复步骤“c”8次;
e) 数据指针加1,如果数据没有全部处理完,则重复步骤b。
f) 寄存器组取反,得到CRC,附加在数据之后,低字节在前,高字节在后。
CRC校验码的计算流程如图2所示。
上述算法为逐位进行运算,效率比较低,不适用于高速通信的场合。数字通信系统(各种通信标准)一般是对一帧数据进行CRC校验,而字节是帧的基本单位。最常用的是一种按字节查表的快速算法。该算法基于这样一个事实:计算本字节后的CRC码,等于上一字节余式CRC码的低8位左移8位,加上上一字节CRC右移8位和本字节之和后所求得的CRC码。如果我们把8位二进制序列数的CRC码(共256个)全部计算出来,放在一个表里,编码时只要从表中查找对应的值进行处理即可。
CRC-ITU的计算算法如下:
a) 寄存器组初始化为全"1"(0xFFFF)。
b) 寄存器组向右移动一个字节。
c) 刚移出的那个字节与数据字节进行异或运算,得出一个指向值表的索引。
d) 索引所指的表值与寄存器组做异或运算。
e) 数据指针加1,如果数据没有全部处理完,则重复步骤b。
f) 寄存器组取反,得到CRC,附加在数据之后,低字节在前,高字节在后。
CRC-ITU的验证算法如下:
a) 寄存器组初始化为全"1"(0xFFFF)。
b) 寄存器组向右移动一个字节。
c) 刚移出的那个字节与数据字节进行异或运算,得出一个指向值表的索引。
d) 索引所指的表值与寄存器组做异或运算。
e) 数据指针加1,如果数据没有全部处理完,则重复步骤b (数据包括CRC的两个字节)。
f) 寄存器组的值是否等于“Magic Value”(0xF0B8),若相等则通过,否则失败。
图2 CRC校验码的计算流程