一、介绍
通过之前几个小节的学习,我们已经知道了数字、字符这些简单的数据应该怎么在计算机内部进行表示。
其实本质上就是一些 0101 的二进制代码,但是这些数据在计算机内部进行计算、存取还有传送的过程当中,由于计算机元器件有可能会发生故障,或者也有可能会因为某些环境噪音干扰,导致我们在计算机内部存储、传输的这些二进制数据会发生错误,所以我们就必须考虑到数据的校验
这样的问题。
中国有一句古话叫知错能改,善莫大焉。在计算机内部,既然数据有可能会发生错误,那我们应该怎么做才能知道,才能发现这种错误的发生呢?
另外,当检测到错误发生之后,应该怎么来改正错误?
这个小结中,我们先介绍一种可以发现数据错误的编码机制,叫做奇偶校验
。
我们会首先简单地介绍校验相关的一些原理,还有基本概念,再来介绍基偶校验应该如何实现。
二、概念
来看这样的一个故事。
两台计算机之间进行数据的传输,他们有可能会传输这样的四种信息A、B、C、D。
由于只有四种,所以我们只需要2个比特位的信息,就可以和这四个信息进行一个一一映射。
现在假设他们想要传输的是 B 信息,也就是二进制的01。
但是现在由于某种神秘的环境因素的干扰,导致了这两个二进制位在传输的过程当中发生了跳变,也就是发生了所谓的位错误, 0 可能会变为1,1可能会变为0。
我们假设是第2个二进制位发生了错误,所以右边这台计算机它最后接收到的数据就变成了00。
所以本来他们想传送的是 B 信息,但是由于环境因素的干扰,右边这台计算机它接收到的实际是A。如下:
由于 00这个信息它也是合法的,所以右边这台计算机它并不能判断出它接收到的数据是不是发生了错误。
现在我们把编码方案进行优化,增加一个冗余的校验位。如下:
由于 2 的三次方等于8,也就是 3 个二进制位本来可以映射为 8 种状态,但是现在我们只取了其中的 4 个状态作为合法的状态,剩下的 4 个是冗余的非法状态。
采用这种编码方案来传输数据,就可以让我们发现某一些二进制位的错误。
还是刚才那个故事,要发送 B 信息, B 所对应的二进制编码是001。
现在在传输的过程中,假设是最后的这一位发生了错误,右边这台计算机就会接收到000的信息。
看一下刚才的表,000这个信息是一个非法的状态,所以此时右边这台计算机就可以判断 000 一定是发生了错误的,就可以让它重新再传输。
三、原理
(1)人类视角
这个原理很简单,如果有 n 个有效的信息位,我们会在这些信息位的首部或者尾部加入1位的奇偶校验位。
如果采用奇校验
的策略,需要保证添加的校验位还有所有的信息位里边,“1”的个数必须是奇数个;偶校验
的策略也是类似的,我们添加了校验位之后,需要保证整体来看 “1” 的个数为偶数个。
直接来看一个例题。
现在我们有这样的两串原始的信息,需要给出他们的奇校验码和偶校验码。
假设我们会在高位的地方添加校验位,剩下的 7 位是信息位。
①先来看奇校验码,可以数一下第一串数据总共有 4 个“1”,因此我们需要在高位再补一个1,这样就可以保证总体来看“1”的个数有奇数个。
第二串信息一共有 5 个“1”,所以我们需要在高位处补一个0,保证整体来看 1 的个数为奇数个。
②再看偶校验码,第一串数据本身就有偶数个1,所以我们需要在首部添0。
第二串数据总共有奇数个1,所以我们需要在首部添一个1,保证整体拥有偶数个1。
来看一下怎么检测出错误。
假设我们采用的是偶校验的一个策略,那么这一串合法的数据在发送的过程中,如果发生了1个比特的信息跳变,比如最末尾的 1 变成了0。
那么当我们接收到数据的时候,数一下总共有 5 个1,这并不符合我们偶校验码的规定。
因此我们就可以判断一定是出问题了,可以要求重新传送。
再来看,如果有两2个比特发生了跳变,比如是最后面的这两个 1 变为了0。
那么接收方经过检查发现,收到的数据当中一共有 4 个1,也有偶数个1,这其实是符合偶校验码的规定的,因此接收方会以为自己收到的是一个合法的数据。
所以,如果有偶数个位发生了错误,那么奇偶校验的这种策略是检测不出错误来的。这是奇偶校验码的局限性。
(2)机器视角
到目前为止,我们是站在人类的视角来探讨如何确定校验位,怎么进行奇偶校验的。
接下来我们来看一下计算机硬件实现这种奇偶校验的原理。
以偶校验的实现为例。
首先我们需要做的是确定一串信息位的校验位到底是多少。这个事情可以通过硬件的异或运算,或者也可以称为模2加的运算来实现。
跨考的同学注意一下异或运算。所谓异或运算,就是给你两个二进制的比特位,当这两个比特位不一样,就是相异的时候,运算的结果为1;而如果两个二进制位相同的时候,运算的结果就是0。如下:
对于第一串信息,我们要求它的偶校验位,只需要把所有的这些比特位都进行异或运算。
1 和0异或等于1,这个1再和0异或还是等于1,这个 1再和下一个1异或应该等于0,再和下一个1进行异或又等于1,1 和0异或等于1,再和最后一个 1异或等于0。如下:
因此,所有的这些位进行异或运算,得到的结果就是0。
这儿我们算得的结果就是偶校验位,和之前得到的结果是一样的。
第二串信息也是一样的,把所有的这些信息位进行异或运算,得的结果是1。
所以第二串信息的偶校验位应该是1。
现在计算机已经得出偶校验位是多少,把它一拼接,就可以得到完整的偶校验码。
接下来再看校验
的过程应该怎么实现,同样需要使用到异或运算。
对所有的二进制位,包括校验位进行异或运算。如果结果为1,说明出错。
现在假设对 01001101 进行偶校验,所有的这些位进行异或运算,大家可以自己推一下,得到的结果是0。
校验的结果符合偶校验的规定,所以我们会认为这串数据它是合法的。
再来看第二串数据,假设这串数据的最后一位发生了错误,由 1 变为了0。
可以推一下这些二进制位进行异或运算,得到的结果是1,说明发生了错误。如下:
而如果原始数据发生了2个比特的跳变,最后得到的结果是0,我们同样会认为它是正确的。
所以用硬件来实现偶校验和我们之前分析的结论是一致的。
如果有偶数个比特发生了错误,我们是无法发现错误的,只有奇数个比特的错误,我们才能检测出来。
再次强调异或运算的规则,跨考的同学一定要注意,因为我们在之后还会经常碰到,异或也可以把它称为模2加。