循环冗余校验,也就是常说的CRC,是通信和存储里最常见的差错检测手段。它的思路不复杂:把要发的数据当成一个很长的二进制数,除以一个约定的生成多项式,得到的余数附在数据后面一起发出去。接收方用同样的多项式再除一遍,余数为零就认为没出错。
这里的除法是模2除法,加减都不进位也不借位,本质就是异或。生成多项式是提前约定好的,比如CRC-16用0x1021,CRC-32用0x04C11DB7。多项式的最高位和最低位必须是1,选得好不好,直接影响能检出哪类错误。工业上常用的那几个多项式,都是经过大量分析挑出来的。
硬件实现就是移位寄存器加异或门,数据一位一位往里移,移完寄存器里的值就是余数。软件实现有两种:按位算是直观但慢,查表法是提前把8位数据的余数算好存成表,运行时一次处理一个字节,速度快很多。单片机资源紧张的时候,一般用半字节表或者按位算,省空间。
实际用CRC要注意参数匹配,不然两边算出来对不上。除了多项式,还有初值、输入是否反射、输出是否异或、结果字节序这几个参数。同样是CRC-16,初值给0x0000和给0xFFFF,结果完全不同。做协议对接时,先把对方的CRC参数问清楚,别自己拍脑袋定。
CRC的定位是检错,不是纠错。它能发现传输中的比特翻转、成串错误,但没法告诉你哪一位错了,发现错误只能重传。所以通信协议里通常是CRC加超时重传,存储介质里是CRC加上层文件系统的校验,多层配合才靠谱。
工程上还有几个细节。计算范围要跟协议一致,有的协议只算数据段,有的把帧头长度都算进去;发出去的CRC字节序是大端还是小端,也要跟接收端对齐。调试时如果CRC老是对不上,先拿一组标准测试向量验证自己的实现,别一上来就怀疑线路。
上一篇:路由器与交换机的区别在哪:二层转发和三层转发各管什么
下一篇:没有了