前言
在数据传输过程中,难免会因为硬件问题,信号干扰,缓存问题,代码逻辑等导致读取到的数据与写入的数据不一致,对于这种错误的数据,我们需要能够及时发现并且进行错误处理。如果把错误的数据当作正常数据使用,会导致不可预料的各种错误。
如何校验数据是否正确,正常做法就是声明一种算法,把数据进行压缩加密,产生一个密文,然后接收端用相同的方法操作一遍,如果密文相同,就可以认定为数据没有修改,如果密文不同,就说明数据发生了变化。
这种算法必须有两大特点,一是尽可能高效,不能因为校验而大大影响传输效率,毕竟增加校验相当于发送端和接收端分别增加一次计算,多了一倍的数据处理;二是能检测出数据变动,不能数据发生了改变,结果校验码仍然是一致的。
常见的有md5、rsa等,这些一般用作加密校验,对效率要求可能没那么高,多了安全性,不能很容易被人破解;还有就是CRC等,一般用作数据传输中的出错校验。
原理
CRC相当于把所有的数据——转成二进制后——当作一个非常大的数字,除以一个数,得到一个余数。然后根据这个余数,把无法整除的差值补在末尾,接收端把这个数字(也就是我们的原始数据)末尾拼接上计算出的差值,再除以同一个除数,理论上余零。这就是CRC算法的思路,如果不能整除,说明数据中间发生了变化。
CRC中使用的是模2的除法,换句话说,就是异或。
举例
数据是10111001
,校验位是4个,先在末尾加4个0(101110010000
),除以一个5位的二进制(因为除以5位,才能得出4位校验),按照异或进行计算,得到余数是1010
——校验位。把1010
替换掉末尾增加的4个0(101110011010
),再除以相同的数,结果为0,表示数据没有修改。
https://info.support.huawei.com/info-finder/encyclopedia/zh/CRC.html
http://www.ross.net/crc/crcpaper.html
http://www.ross.net/crc/download/crc_v3.txt