计算机组成原理·海明编码及其实验

前言:海明编码这一块在刚开始的时候没有弄懂,后面通过做实验、复习慢慢摸清了门道。在学习计算机组成原理的过程中,实验实践是很重要的,它会让你去搞清楚事情背后的原理,逼着你学会你没听懂的东西。这篇文章会从海明码的理论部分实验部分进行阐述。

海明码

奇偶校验码

  为什么要谈到奇偶校验码呢?因为它和海明码一样,都属于校验码。所谓校验码,就是数据位校验位的合并,通过校验位的信息,你能知道数据是不是出错了,哪里出错了,它本应是多少。

注:后文均用 k k k 表示原式数据位数, r r r 表示校验位位数(也同时是校验组的组数), n n n 表示校验码(数据位 + 校验位)的总位数。

  正如上图所示,校验码主要是用于数据发送方和接收方通信用的,通过校验位可以检查传过来的数据是否准确。
  偶校验码通过设置 r = 1 r=1 r=1 位校验位 P P P,使得校验码 P D k ⋯ D 2 D 1 PD_k\cdots D_2D_1 PDkD2D1 所有位共有偶数个 1 1 1。计算公式是
P = D 1 ⊕ D 2 ⊕ ⋯ ⊕ D k (1) P=D_1\oplus D_2\oplus\cdots\oplus D_k\tag 1 P=D1D2Dk(1)

  比如发送方需要传输 k = 5 k=5 k=5 位数据 11001 11001 11001,会生成一位校验位 1 1 1,打包成校验码 1 11001 \red{1}11001 111001 送给接收方。如果传输过程没有发生错误,接收方收到的就是 111001 111001 111001,看一下有 1 1 1 的个数是偶数,应该是没问题。如果传输过程中有一位出错了,比如 111001 → 11 0 001 111001\rightarrow 11\red 0001 111001110001,接收方收到的数据就有奇数个 1 1 1,所以就能够判断传过来的数据出错了(但是不能分辨是哪一位错了)。
  奇偶校验码的缺点也是显而易见的,对偶校验码来说,如果传输过程中出现了 2 2 2 位错误,接收方就会认为是正确的,这说明奇偶校验码最多检错 1 1 1

码距

  定长编码中任意两个合法编码最少有多少位不同,这个编码的码距就是多少。比如上面的奇偶校验码码距就是 2 2 2。海明码的码距是 3 3 3

海明码

有多种类型的海明码校验,这里只介绍能纠一位错的海明码。

多校验组

  前面提到,奇偶校验码可以检测 1 1 1 位错,但是不具备纠错能力。并且所有数据位于 1 1 1 个校验组中,即 r = 1 r=1 r=1
  海明码在 k k k 位数据位中插入 r r r 个校验位,使得每个数据至少位于 2 2 2 个校验组中(为什么?后面会解释)。也就意味着对于某个 D s D_s Ds 而言,它至少要参与 P i P_i Pi P j ( i ≠ j ) P_j(i\neq j) Pj(i=j) 的生成。同样的, P i P_i Pi 是由某一些数据位异或得到的, P i P_i Pi 和这些数据位共同构成 1 1 1校验组(偶校验组)。
P i = D i 1 ⊕ D i 2 ⊕ ⋯ ⊕ D i t (2) P_i=D_{i1}\oplus D_{i2}\oplus \cdots\oplus D_{it}\tag 2 Pi=Di1Di2Dit(2)

  式 ( 2 ) (2) (2) 描述了第二个第 i i i 个校验位的生成。

省流:每个校验组都是由一个 P P P 和若干 D D D 构成的, P P P 是这些 D D D 的异或结果。

  接收方会生成一种叫检错码的东西,每个校验位生成 1 1 1 个检错码,所以一共有 r r r 个检错码,用 G i ( i = 1 , 2 , ⋯   , r ) G_{i}(i=1,2,\cdots,r) Gi(i=1,2,,r) 来表示。 接收方会干这样的事情:
G i = P i ′ ⊕ D i 1 ′ ⊕ D i 2 ′ ⊕ ⋯ ⊕ D i t ′ (3) G_i=P_i'\oplus D_{i1}'\oplus D_{i2}'\oplus\cdots\oplus D_{it}'\tag 3 Gi=PiDi1Di2Dit(3)

  其中加一个 ′ ' 表示数据传输后的结果,比如发送方的 D 4 D_4 D4 在接收方变成了 D 4 ′ D_4' D4

注意 G i G_i Gi(检错码) 和 P i P_i Pi (校验码)是不同的东西, P i P_i Pi发送方根据 D D D 生成的; G i G_i Gi接收方根据 P i ′ P_i' Pi D ′ D' D 生成的,用于检错。海明码的实现中结合了偶校验的思想。

  显然,如果接收方发现 G i = 1 G_i=1 Gi=1,就说明第 i i i 个校验组有数据出错了。但是到底是谁出错了?是 P i P_i Pi 还是对应的 D i t D_{it} Dit 呢?

海明码原理

  海明码致力于制定一套规则回答上面的问题。它将 k k k 个数据位 D D D r r r 个校验位 P P P某种方式组合成 n n n 位校验码 H H H,以某种方式划分校验组,以期达到这样的目标: G r ⋯ G 1 G_r\cdots G_1 GrG1 直接指示出错的位置。比如 G 3 G 2 G 1 = 011 G_3G_2G_1=011 G3G2G1=011,代表海明码的 H 3 H_3 H3 出错了。其中,预留 G 3 G 2 G 1 = 000 G_3G_2G_1=000 G3G2G1=000 代表没有错误。
  因此,对于海明码 n = k + r n=k+r n=k+r 位来说, 1 1 1 位错一共有 k + r k+r k+r 种可能,但是 G r ⋯ G 1 G_r\cdots G_1 GrG1 只能指示 2 r − 1 2^r-1 2r1 种错误。所以应该有:
k + r ≤ 2 r − 1 (4) k+r\leq 2^r-1\tag4 k+r2r1(4)

  并且,由于海明码要实现纠错功能,码距就不能是 2 2 2,至少要是 3 3 3,否则就会像奇偶校验码一样只能检错、不能纠错。为了减少冗余,海明码的码距设定为 3 3 3。这就意味着每个数据位 D s D_s Ds 至少要出现在 2 2 2 个校验组中。

假设数据位 D s D_s Ds 只出现在校验组 P i P_i Pi 中。当 D s = 0 D_s=0 Ds=0 时,记 P i = k P_i=k Pi=k,得到的海明码是 H \boldsymbol H H;当 D s = 1 D_s=1 Ds=1 时,根据异或的性质,有 P i = k ‾ P_i=\overline k Pi=k,得到的海明码是 H ′ \boldsymbol {H'} H。你会发现 H \boldsymbol H H H ′ \boldsymbol{H'} H 只有 D s D_s Ds P i P_i Pi 两位是不一样的,那么海明码的码距就是 2 2 2。但是我们海明码的码距是 3 3 3,所以 D s D_s Ds 只出现在一个校验组是不够的。

  现在我们来看海明码是怎么编码的。假设 r = 3 r=3 r=3 的海明码,检错位是 G 3 G 2 G 1 = 001 G_3G_2G_1=001 G3G2G1=001——这说明只有校验组 1 1 1 出错了。那可能是生成 P 1 P_1 P1 的那些 D D D 出错了吗?不可能,因为一旦 D D D 出错, G 3 G 2 G 1 G_3G_2G_1 G3G2G1 就至少有两个 1 1 1(至少两个校验组出错)了,因为每个数据位都至少要出现在 2 2 2 个校验组中。
  所以,对于 G 3 G 2 G 1 G_3G_2G_1 G3G2G1 只有一位 1 1 1 的情况,只能是校验组所对应的检错位出错了。
  那么 G 3 G 2 G 1 = 001 / 010 / 100 G_3G_2G_1=001/010/100 G3G2G1=001/010/100 分别对应检错位 P 1 , P 2 , P 3 P_1,P_2,P_3 P1,P2,P3 出错,根据海明码的目标“ G r ⋯ G 1 G_r\cdots G_1 GrG1 直接指示出错的位置”,应该把 P 1 P_1 P1 放在 H 1 H_1 H1 P 2 P_2 P2 放在 H 2 H_2 H2 P 3 P_3 P3 放在 H 4 H_4 H4。且看下面的表格:

海明码 H 1 H_1 H1 H 2 H_2 H2 H 3 H_3 H3 H 4 H_4 H4 H 5 H_5 H5 H 6 H_6 H6 H 7 H_7 H7
检错码/位置
G 3 G 2 G 1 G_3G_2G_1 G3G2G1
001 001 001 010 010 010 011 011 011 100 100 100 101 101 101 110 110 110 111 111 111
映射关系
(这一位 H H H 放什么)
P 1 P_1 P1 P 2 P_2 P2 D 1 D_1 D1 P 3 P_3 P3 D 2 D_2 D2 D 3 D_3 D3 D 4 D_4 D4
属于 G 1 G_1 G1 校验组
属于 G 2 G_2 G2 校验组
属于 G 3 G_3 G3 校验组

  这个表格是对应海明码在 ( n , k ) = ( 7 , 4 ) (n,k)=(7,4) (n,k)=(7,4) 时的分组规则。预留了 G 3 G 2 G 1 = 000 G_3G_2G_1=000 G3G2G1=000 ,对应海明码没有出错。其实上面 D D D 的位置是可以随便放的,这个只影响后面校验位 P P P 的生成表达式。按照上面的 D D D 的放置方式,有:
{ P 1 = D 1 ⊕ D 2 ⊕ D 4 P 2 = D 1 ⊕ D 3 ⊕ D 4 P 3 = D 2 ⊕ D 3 ⊕ D 4 (5) \begin{cases}P_1=D_1\oplus D_2\oplus D_4\\P_2=D_1\oplus D_3\oplus D_4\\P_3=D_2\oplus D_3\oplus D_4\end{cases}\tag 5 P1=D1D2D4P2=D1D3D4P3=D2D3D4(5)

  式 ( 5 ) (5) (5) 是发送方要干的事情。给发送方一个 D 4 D 3 D 2 D 1 D_4D_3D_2D_1 D4D3D2D1,发送方需要按照 ( 5 ) (5) (5) 生成 P 3 P 2 P 1 P_3P_2P_1 P3P2P1,然后打包成 H 7 H 6 H 5 H 4 H 3 H 2 H 1 = D 4 D 3 D 2 P 3 D 1 P 2 P 1 H_7H_6H_5H_4H_3H_2H_1=D_4D_3D_2P_3D_1P_2P_1 H7H6H5H4H3H2H1=D4D3D2P3D1P2P1,发送给接收方。
  根据式 ( 2 ) ( 3 ) (2)(3) (2)(3),接收方需要按照下面的方式生成检错位:
{ G 1 = P 1 ′ ⊕ D 1 ′ ⊕ D 2 ′ ⊕ D 4 ′ G 2 = P 2 ′ ⊕ D 1 ′ ⊕ D 3 ′ ⊕ D 4 ′ G 3 = P 3 ′ ⊕ D 2 ′ ⊕ D 3 ′ ⊕ D 4 ′ (6) \begin{cases}G_1=P_1'\oplus D_1'\oplus D_2'\oplus D_4'\\ G_2=P_2'\oplus D_1'\oplus D_3'\oplus D_4'\\ G_3=P_3'\oplus D_2'\oplus D_3'\oplus D_4'\end{cases}\tag 6 G1=P1D1D2D4G2=P2D1D3D4G3=P3D2D3D4(6)

  根据生成的 G 3 G 2 G 1 G_3G_2G_1 G3G2G1,接收方能够判断有没有出错,是谁出错了。

海明码的检错与纠错

  海明码的检错、纠错能力是有限的。由于码距是 3 3 3,因此它最多能够检测 2 2 2 位错;但是它不能区分 1 1 1 位错和 2 2 2 位错。同时,它只能够纠正 1 1 1 位错。

检测 2 2 2 位错的含义是,编码在传输过程中有 2 2 2 位出错,接收方拿到之后能够识别到异常;而不是接收方拿到数据,说我发现你发送过来的数据里面有 2 2 2 位错。

  举个例子,数据传输过程中 D 1 D_1 D1 出错,接收方得到的是 G 3 G 2 G 1 = 011 G_3G_2G_1=011 G3G2G1=011;但是如果 D 2 , D 3 D_2,D_3 D2,D3 同时出错,那么接收方得到的还是 G 3 G 2 G 1 = 011 G_3G_2G_1=011 G3G2G1=011。所以只有在假定最多发生 1 1 1 位错的前提条件下,海明码才能够正确地检错并纠错。

拓展海明码

  前面说了海明码不能区分 1 1 1 位错和 2 2 2 位错。如果再引入一个总偶校验位 P a l l P_{all} Pall,就能够分辨一位错和两位错。
P a l l = H n ⊕ ⋯ ⊕ H 2 ⊕ H 1 (7) P_{all}=H_n\oplus \cdots\oplus H_2\oplus H_1\tag7 Pall=HnH2H1(7) G a l l = P a l l ′ ⊕ H n ′ ⊕ ⋯ ⊕ H 2 ′ ⊕ H 1 ′ (8) G_{all}=P_{all}'\oplus H_n'\oplus \cdots\oplus H_2'\oplus H_1'\tag8 Gall=PallHnH2H1(8)

   ( 7 ) (7) (7) 是发送方做的事情, ( 8 ) (8) (8) 是接收方做的事情。假设没有 3 3 3 位错,接收方在发现 G 3 G 2 G 1 ≠ 000 G_3G_2G_1\neq 000 G3G2G1=000 即有错的条件下,可利用 G a l l G_{all} Gall 判断是一位错 ( G a l l = 1 ) (G_{all}=1) (Gall=1) 还是两位错 ( G a l l = 0 ) (G_{all}=0) (Gall=0)

海明码实验

海明编码

在这里插入图片描述
  实际上就是填写分组规则表,像前文的那个表格一样。这里原始数据有 k = 16 k=16 k=16 位,检错位有 r = 5 r=5 r=5 位加上 1 1 1 P a l l ( P 6 ) P_{all}(P_6) Pall(P6) P 1 P_1 P1~ P 5 P_5 P5 的线路连接参考式 ( 2 ) ( 5 ) (2)(5) (2)(5) P 6 P_{6} P6 的线路连接参考式 ( 7 ) (7) (7)

海明解码实验

在这里插入图片描述
  参考 ( 3 ) ( 6 ) (3)(6) (3)(6),根据分组规则表生成 G 1 G_1 G1~ G 5 G_5 G5 G 6 G_6 G6 根据 ( 8 ) (8) (8) 式生成。这里面多路选择器根据检错码 G \boldsymbol G G 的情况,选择一个数与原来的数据 D \boldsymbol D D 异或一下,使得异或的数据能够恢复成正确的数据。

资源获取

华中科技大学计算机组成原理实验
华中科技大学计算机组成原理实验——数据表示实验

  • 34
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值