前置知识
结合律
模二除法的余数满足结合律:两数的余数异或等于两数异或后的余数
$$
(M(x) % G(x)) \oplus (N(x) % G(x)) = (M(x) \oplus N(x)) % G(x)
$$
例如,已知发送方发送数据1100010,生成多项式G(x)=1011,1100010 mod 1011=000.
正确的情况
如果收到1100010,拿它除以生成多项式,1100010 mod 1011=000,余数为0说明数据传输正确。
错误的情况
假设最低位出错了,收到的数据是0100010
$$
\begin{equation}
\begin{aligned}
0100010 &= 1100010 \oplus 1000000 \
0101000 mod 1101 &= (1100010 mod 1011) \oplus (1000000 mod 1011) \
&= 000 \oplus 101 \
&= 101
\end{aligned}
\end{equation}
$$
所以如果接收方收到0100010,得到余数101表示错误在最高位。
CRC编码的非0余数具有循环特性
将余数左移一位除以生成多项式,将得到下一个余数,继续重复在新余数的基础上左移一位除以生成多项式,余数最后能循环为最开始的余数。
举个例子,假设正确的数据为1100010,G(x)=1011
比如最低位出错,收到的数据为1100011,余数为001,001左移一位得0010,再除以G(x)得010,这就是倒数第二位出错得到的余数。
一直重复这个过程,当余数为101,即最高位出错时我们修改最高位得到正确的值,继续操作直到余数回到001,说明出错位已经回到原来的位置,而且我们已经纠错过出错位了,所以得到了正确的数据。
说明 | 校验码现在的值 | 运算 | 余数 |
---|---|---|---|
发现出错, 开始纠错 | 1100011 | 1101011与G(x)做模二除 | 001 |
001补0=0010 | 1000111 | 0010与G(x)做模二除 | 010 |
010补0=0100 | 0001111 | 0100与G(x)做模二除 | 100 |
100补0=1000 | 0011110 | 1000与G(x)做模二除 | 011 |
011补0=0110 | 0111100 | 0110与G(x)做模二除 | 110 |
110补0=1100 | 1111000 | 1100与G(x)做模二除 | 111 |
111补0=1110 | 1110001 | 1110与G(x)做模二除 | 101 |
101补0=1010 | 1100011 | 1010与G(x)做模二除 | 001 |
这时我们发现余数回到了最开始的001,原本出错的位又回到了原来的位置。
纠错过程
一边对余数补0进行模二除,同时让被检测的校验码循环左移,当余数为101时,出错位也移到最高位(这一点我们之前在结合律的例子中算过了)。通过异或运算纠正后继续循环左移和执行余数模二除法,直到回到原来的余数,修改后的出错位回原位。 这样循环移位的方法的好处是,不需对每一位提供纠正电路,只需在最高位添加纠正电路,对于位数很长的数据效率很高。
说明 | 校验码现在的值 | 运算 | 余数 |
---|---|---|---|
发现出错, 开始纠错 | 1100011 | 1101011与G(x)做模二除 | 001 |
001补0=0010 | 1000111 | 0010与G(x)做模二除 | 010 |
010补0=0100 | 0001111 | 0100与G(x)做模二除 | 100 |
100补0=1000 | 0011110 | 1000与G(x)做模二除 | 011 |
011补0=0110 | 0111100 | 0110与G(x)做模二除 | 110 |
110补0=1100 | 1111000 | 1100与G(x)做模二除 | 111 |
111补0=1110,此时余数101,我们将最高位异或1,得到0110001 | 1110001 | 1110与G(x)做模二除 | 101 |
101补0=1010,0110001循环左移 | 1100010 | 1010与G(x)做模二除 | 001 |
在倒数第二行,余数为101,说明出错位已经移到了最高位,我们将最高位异或1
$$1110001\oplus 1000000=0110001$$
得到0110001,这样就纠正了出错位。
继续循环直到余数回到001,也就是最后一行,说明出错位已经回到原来的位置,而且我们已经纠错过出错位了,所以得到了正确的数据1100010。
为什么不查表?(个人理解)
把每个位出错得到的余数写一张表,收到数据算出余数比对,不就知道哪位出错了,修改对应位就好了?
这样是挺快的,但是当位数很多时,表很大,而且要对每一位提供纠错电路,这样开销就大了。