奇偶校验(Parity Check)是一种校验代码传输正确性的方法。根据被传输的一组二进制代码的数位中“1”的个数是奇数或偶数来进行校验。采用奇数的称为奇校验,反之,称为偶校验。采用何种校验是事先规定好的。通常专门设置一个奇偶校验位,用它使这组代码中“1”的个数为奇数或偶数。若用奇校验,则当接收端收到这组代码时,校验“1”的个数是否为奇数,从而确定传输代码的正确性。
说白了,就是统计每一位的“1”是奇数还是偶数,进而将校验位设置为0或1,当然也能够看到缺点十分明显:如果只有一位电平变化,能够检查出来。如果是有两个电平变化,就检查不出来了。优点就是是需要一位校验位,传输数据的效率非常高。
海明码的编码和校验方法 - acquisitive - 博客园
海明码(也叫汉明码)具有一位纠错能力。本文以1010110这个二进制数为例解释海明码的编码和校验方法。
确定校验码的位数x
设数据有n位,校验码有x位。则校验码一共有2x种取值方式。其中需要一种取值方式表示数据正确,剩下2x-1种取值方式表示有一位数据出错。因为编码后的二进制串有n+x位,因此x应该满足
2^x-1 ≥ n+x
使不等式成立的x的最小值就是校验码的位数。在本例中,n=7,解得x=4。
确定校验码的位置
校验码在二进制串中的位置为2的整数幂。剩下的位置为数据。如图所示。
位置 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
内容 |
x1 |
x2 |
1 |
x3 |
0 |
1 |
0 |
x4 |
1 |
1 |
0 |
求出校验位的值
以求x2的值为例。为了直观,将表格中的位置用二进制表示。
位置 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
0111 |
1000 |
1001 |
1010 |
1011 |
内容 |
x1 |
x2 |
1 |
x3 |
0 |
1 |
0 |
x4 |
1 |
1 |
0 |
为了求出x2,要使所有位置的第二位是1的数据(即形如**1*的位置的数据)的异或值为0。即x2^1^1^0^1^0 = 0。因此x2 = 1。
同理可得x1 = 0, x3 = 1, x4 = 0。
位置 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
0111 |
1000 |
1001 |
1010 |
1011 |
内容 |
0 |
1 |
1 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
0 |
因此1010110的海明码为01110100110。
校验
假设位置为1011的数据由0变成了1,
位置 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
0111 |
1000 |
1001 |
1010 |
1011 |
内容 |
0 |
1 |
1 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
校验过程为:
将所有位置形如***1, **1*, *1**, 1***的数据分别异或。
***1: 0^1^0^0^1^1 = 1
**1*: 1^1^1^0^1^1 = 1
*1**: 1^0^1^0 = 0
1***: 0^1^1^1 = 1
以上四组中,如果一组异或值为1,说明该组中有数据出错了。***1 **1* 1***的异或都为1,说明出错数据的位置为1011。
在我理解,从原理上来讲,海明码是用几个校验位来插在几个特殊的位置,比如0001、0010、0100这三个位置,每个位置放置1位校验位,那么可以看护2^3-3-1>=4个数据位,为啥-1呢,因为0000的位置空出来不用。
这样的话,通过按照位所在的地址分类可以将某些数据位进行异或运算,异或运算出的结果就是该位置校验位的值,比如说某位置, 我们定为**1*, 将数位中含有该地址的a异或b=c,c就是该位置校验位的值,那么在校验的时候又根据异或的运算法则,a异或b异或c=0,如果不为0,就表明该位置数据和校验位的异或有问题,一定是有一位是错的,但是具体是哪一个数据位还是校验位错了并不知道。
好了,我们继续分析,假设是校验位c错了,数据位都是对的,那么0010位置异或后为1,其他都为0,自然表达出0010位是错的;若是数据位某一位错了,比如说是0011位置上的数据位错的,**1*、***1位做异或运算,结果为1。怎么说?能说明0011位置上数据位错了么?当然不行,万一0111位置上错的,也会影响前两位的异或运算,因此我们要把每一位都做异或运算,就能够证明确实是0011位的错了。
说白了,海明码就是通过在关键位插入数据位,让某个数据位在多个位置上进行异或运算,从而确定哪一位出错。缺点很明显,就是只能有一位出错,才可以,如果两位出错,两者异或后也会为0,但是与其他位异或又为1,造成错误位的判断错误。并且相比较奇偶校验需要的校验位也多,校验算法也麻烦一些,整体效率不如奇偶校验;优点也很明显,如果只有一位出错能够找到是哪一位出错,由于位只有1、0,自然也可以通过翻转来纠错。当然,是否要纠错就看是不是确定只有1位出错了。
奇偶校验码(PCC)只能校验一位错误,循环冗余校验码(CRC)的检错能力更强,可以检出多位错误。
1. CRC校验原理
CRC校验原理看起来比较复杂,好难懂,因为大多数书上基本上是以二进制的多项式形式来说明的。其实很简单的问题,其根本思想就是先在要发送的帧后面附加一个数(这个就是用来校验的校验码,但要注意,这里的数也是二进制序列的,下同),生成一个新帧发送给接收端。当然,这个附加的数不是随意的,它要使所生成的新帧能与发送端和接收端共同选定的某个特定数整除(注意,这里不是直接采用二进制除法,而是采用一种称之为“模2除法”)。到达接收端后,再把接收到的新帧除以(同样采用“模2除法”)这个选定的除数。因为在发送端发送数据帧之前就已通过附加一个数,做了“去余”处理(也就已经能整除了),所以结果应该是没有余数。如果有余数,则表明该帧在传输过程中出现了差错。
讲解CRC的有很多,这个用途也比较广泛,在串口工具不都有CRC的选项么,在代码中也可以实现CRC。原理先留个坑吧。
CRC码计算及校验原理的最通俗诠释 - 苦涩的茶 - 博客园