计算机组成原理学习笔记:海明校验码

article/2025/10/31 20:21:35

概述

  • 海明校验码又可以称为汉明校验码, 这只是一个音译的问题, 作者是 Richard Hamming
  • 海明校验码对于信息纠错这个领域的贡献十分巨大,Richard Hamming 获得了1968年的图灵奖
  • 内容主要包括:海明校验码的思想、如何构建海明校验码、如何使用海明校验码

海明校验码的思想

回顾奇偶校验码

  • 奇校验码: 整个校验码(有效信息位和校验位) 中 “1” 的个数为奇数
  • 偶校验码: 整个校验码(有效信息位和校验位) 中 “1” 的个数为偶数
  • 其思想是:对于n个有效的信息位, 我们只需要在首部或者尾部添加一个奇校验位或者偶校验位,用这样的方式构成奇偶校验码
  • 比如对于偶校验来说,1010 这4个信息位,我们需要在头部添加一个0,即:01010, 保证整体来看总共有偶数个1
  • 奇偶校验码的一个局限性就是我们只能发现奇数位的错误,但我们无法确定是哪一位出了错,没办法自动的把它进行修正,只能要求数据的传输方重新传送
  • 由于奇偶校验的策略我们只添加了一个校验位,也就是一个比特的信息,而一个比特的冗余信息,显然它只能携带两种状态,也就是只能反馈对或者错这样的两种状态

海明校验码

  • 海明码是基于偶校验的一个拓展, 对于n个有效的信息,我们会把它分为k个分组,然后对k的分数分别的进行偶校验
  • 也就是说每一个分组会对应一个校验位,最终我们会携带k个校验位, 可以反映更多种状态的信息
  • 除了反馈对错之外,我们还可以知道哪一位出了错, 这就是海明码的设计思想
  • 基于这个思路,需要探讨几个问题
    • 第1个问题,我们需要把这n个信息位分为多少个分组
    • 第2个问题这n个信息位,我们怎么把他们分派到各个分组当中
    • 第3个问题是基于海明校验码进行检错和纠错

1 ) 需要设置多少个校验位

  • 假设信息位(n个) 添加的冗余校验位(k个)
  • 我们期待,这k个校验位除了能反映对错之外,还能指明是哪一个比特位出现了错误
  • k个比特能表示2的k次方种状态,而海明校验码整体来看,是信息位 + 校验位
  • 也就是说, 海明校验码位数 = n + k, 而这n+k位都可能出错
  • 那么这2的k次方种状态当中需要包含n+k种情况,那除了出错的这n+k种情况之外,还需要包含一种正确的状态
  • 因此我们可以得到这样的一个不等式: 2 k ≥ n + k + 1 2^k \geq n + k + 1 2kn+k+1, 我们需要通过这个不等式来确定我们需要添加多少个校验位
  • 如果有4个信息位,那么我们就只能取k等于3才能满足这个式子: 2 3 ≥ 4 + 3 + 1 2^3 \geq 4 + 3 + 1 234+3+1
  • 下面这个表给出了n和k的一般对应关系,可记忆,或者自己推
n12-45-1112-2625-5758-120
k234567
  • 基于上述结论,如果说有4个信息位的话,那么我们可以确定我们要添加的校验位的数量k=3,也就是说最终我们生成的海明校验码应该是4+3=7位

2 ) 如何分组

  • 为了区分信息位和校验位, 我们用D1D4来表示这4个信息位,然后用P1P3来表示这三个校验位,用H1~H7来分别对应最终的这7位海明码
  • 那这些信息位和校验位应该放到什么位置呢?
    • 一个很容易想到的办法是把这三个校验位放到头部的位置,然后把4个信息位放到尾部的位置
    • 但是海明码不能这么做,有一些特殊的规定,在海明校验码中规定所有的校验位 P i P_i Pi应该分别放在 2 i − 1 2^{i - 1} 2i1这些位置上
    • 也就是说P1P2P3,这几个校验位,应该分别把他们放到: 第1、2、4这几个位置,那如果还有一个校验位P4的话,那显然应该放到第8的位置
    • 规律是:和我们二进制的权值的上升关系是相符合的, 比如:1、2、4、8、16
    • 所以我们可以把这些校验位所放的位置, 看作是这个校验位它所对应的某一种权值
    • 总之, P1放到第1个位置,然后P2放到第2个位置,P3要放到第4个位置,剩下位置存放其他的信息位, 如下表所示
H7H6H5H4H3H2H1
D4D3D2P3D1P2P1
1010
  • 目前为止我们已经确定了,基于上述的例子,我们需要添加三个校验位
  • 或者换一个角度来说,需要把这些信息被分为三个分组,每个分组分别进行偶校验
  • 因此接下来我们应该确定一种规则,就是三个分组当中应该分别包含哪几个信息位
  • 当我们确定了如何分组之后,那么与这个分组相对应的偶校验位的值就很好确定了
  • 来看一下怎么做,需要把这些信息为他所处的位置的序号用二进制的形式表示
  • 比如,对于D1这个信息来说,它所处的位置是3, 那么3的二进制表示应该是011, 每个二进制位的权重是1、2、4(从低到高),011的值就是2+1=3
  • 而下一个信息位是D2,它所处的位置是5,那么我们用二进制表示应该是101,此时,4+1=5
  • 而D3所处的位置是6,那么6用二进制表示应该是110,此时,4+2=6
  • 最后是D4,它处于7这个位置,用二进制表示就是111, 此时,4+2+1=7
  • P1、P2、P3 分别把它放到1、2、4这些位置,我们可以把它理解为某一种权重,那么这些权重和刚才提到的这三位二进制的权重是一一对应的
    • H3: 3 -> 011
    • H5: 5 -> 101
    • H6: 6 -> 110
    • H7: 7 -> 111
  • 所以P1这个偶校验位,它所处的分组当中应该有哪些信息位呢?我们只需要把末位为1的这几个信息未把它归为P1所属的分组就可以了
  • 也就是如上:H3、H5、H7这几个位置所对应的信息位归为同一个分组,进行偶校验: P 1 = H 3 ⊕ H 5 ⊕ H 7 = D 1 ⊕ D 2 ⊕ D 4 = 0 P_1 = H_3 \oplus H_5 \oplus H_7 = D_1 \oplus D_2 \oplus D_4 = 0 P1=H3H5H7=D1D2D4=0
  • 只需要把这个组里面的所有信息位进行异或运算,就可以确定我们的P1应该取0还是取1, 这就是P1的一个计算方式
  • 接下来第2个分组,我们应该让它包含H3、H6和H7所对应的这几个信息位, 获得偶校验位: P 2 = H 3 ⊕ H 6 ⊕ H 7 = D 1 ⊕ D 3 ⊕ D 4 = 1 P_2 = H_3 \oplus H_6 \oplus H_7 = D_1 \oplus D_3 \oplus D_4 = 1 P2=H3H6H7=D1D3D4=1
  • 最后一个分组的确定方法也是一样的:H5、H6、H7, 也就是D2、D3、D4,它们从属于同一个分组,把它们异或可以得到偶校验位的值: P 3 = H 5 ⊕ H 6 ⊕ H 7 = D 2 ⊕ D 3 ⊕ D 4 = 0 P_3 = H_5 \oplus H_6 \oplus H_7 = D_2 \oplus D_3 \oplus D_4 = 0 P3=H5H6H7=D2D3D4=0, 这时候我们已经全部确定了海明校验码的值
H7H6H5H4H3H2H1
D4D3D2P3D1P2P1
1010010

3 ) 检错和纠错

  • 怎么检测出错误呢?其实就是把各个分组内的这些二进制比特币进行一个异或运算, 也就是对这个分组进行偶校验
  • 如果说这个分组内没有出错的话,那么进行异或运算得到的结果应该是0
  • 如果现在接收方接收到的数据没有发生任何一个比特的错误,即:1010010,我们根据刚才确定的这三个分组对每个分组内的这些比特位依次进行异或运算
  • 因为每个分组都有偶数个1,所以异或之后肯定都是000,这是没有出错的情况
    • S 1 = P 1 ⊕ D 1 ⊕ D 2 ⊕ D 4 = 0 ⊕ 0 ⊕ 1 ⊕ 1 = 0 S_1 = P_1 \oplus D_1 \oplus D_2 \oplus D_4 = 0 \oplus 0 \oplus 1 \oplus 1 = 0 S1=P1D1D2D4=0011=0
    • S 2 = P 2 ⊕ D 1 ⊕ D 3 ⊕ D 4 = 1 ⊕ 0 ⊕ 0 ⊕ 1 = 0 S_2 = P_2 \oplus D_1 \oplus D_3 \oplus D_4 = 1 \oplus 0 \oplus 0 \oplus 1 = 0 S2=P2D1D3D4=1001=0
    • S 3 = P 3 ⊕ D 2 ⊕ D 3 ⊕ D 4 = 0 ⊕ 1 ⊕ 0 ⊕ 1 = 0 S_3 = P_3 \oplus D_2 \oplus D_3 \oplus D_4 = 0 \oplus 1 \oplus 0 \oplus 1 = 0 S3=P3D2D3D4=0101=0
  • 如果说接收方接收到的数据为:1010000,H2这一位发生了错误,也就是P2这个校验位从1变成了0
  • 第1个分组进行异或得到了0,第2个分组中由于P2发生了跳变,所以导致第2个分组中,现在只有奇数为1,那么异或出来的结果就是1
  • 而第3个分组没有任何一个数据发生跳变,因此异或的结果应该是0
    • S 1 = P 1 ⊕ D 1 ⊕ D 2 ⊕ D 4 = 0 ⊕ 0 ⊕ 1 ⊕ 1 = 0 S_1 = P_1 \oplus D_1 \oplus D_2 \oplus D_4 = 0 \oplus 0 \oplus 1 \oplus 1 = 0 S1=P1D1D2D4=0011=0
    • S 2 = P 2 ⊕ D 1 ⊕ D 3 ⊕ D 4 = 0 ⊕ 0 ⊕ 0 ⊕ 1 = 1 S_2 = P_2 \oplus D_1 \oplus D_3 \oplus D_4 = 0 \oplus 0 \oplus 0 \oplus 1 = 1 S2=P2D1D3D4=0001=1
    • S 3 = P 3 ⊕ D 2 ⊕ D 3 ⊕ D 4 = 0 ⊕ 1 ⊕ 0 ⊕ 1 = 0 S_3 = P_3 \oplus D_2 \oplus D_3 \oplus D_4 = 0 \oplus 1 \oplus 0 \oplus 1 = 0 S3=P3D2D3D4=0101=0
  • 现在根据S1~S3组成的数就可以确定,是010这个位出现了错误,那010转换成10进制是2
  • 也就是说S3S2S1所组成的这个二进制数指明了我们出错的位置在哪, 如果所得的结果110的话,那么就说明出错的位置是在6这个位置
  • 这么神奇的规律背后是什么原理呢?如下图所示
  • 这个图里边每一个圆圈表示的是从属于同一个分组的比特位
  • P1、D1、D2、D4 从属于同一个分组
  • P2、D1、D3、D4 从属于第2个分组
  • P3、D2、D3、D4 从属于第3个分组
  • 而这三个分组相互之间是有交集的,如果D3这个信息位发生了跳变,由于第2个分组和第3个分组都包含了D3这个信息位
  • 因此D3的跳变会导致S2和S3算出来的结果都是1,而S1中所有的信息位都没有跳变,因此, 它出来的结果肯定是0
  • 我们最终得到的S3~S1,结果是110, 这个数等于6刚好就指向了D3所对应的位置
  • 再比如,假定了P2发生了跳变,那么P2它只从属于第2个分组,因此它只会影响S2的值,而得到的结果,010刚好又是指向了P2所处的位置
  • 再举一个例子,如果说是D4发生了跳变,D4从属于所有的这些分组, 因此所有的分组的偶校验,或者说这个异或运算结果
  • 肯定都会被影响的, 111对应的十进制是7, 刚好指向了D4它所处的这个位置,这就是海明码的一个纠错原理

海明码的格式变化

  • 有时候,海明码的编号是从小到大,但是我们上面探讨的是从大到小
  • 其实从小到大的做法是一模一样的,只不过是左右方向换了而已,在做法上没有任何区别
  • 而另外一个要补充的具有一个比特位的纠错能力

海明码的缺点

  • 海明码有1个比特位的纠错能力,有两个比特位的检错能力
  • 这里有一个例子,假设我们在传输的过程当中,P1和P2这两个校验位发生了跳变,那么得到的结果就是S1=1, S2=1, S3=0
  • 那么按照之前的规则011对应的十进制是3,那这是否说明了H3这个位置出现了错误呢?显然这个结论是不对的
  • 此时我们是发生了两个比特位的跳变,我们是没有办法区分到底是一个比特位的错误,还是两个比特位的错误
  • 为了解决这个问题实际海明码在使用的时候通常还会在最首部加上一个全校验位
  • 所谓全校验就是对我们之前得到的全部的比特信息,统一的进行一次偶校验
  • 在上述这个例子当中总共有三个1,所以这个全校验位,我们应该把它设定为1,保证整体来看有偶数个1
H8H7H6H5H4H3H2H1
P全D4D3D2P3D1P2P1
11010010
  • 如果我们求得的S1 ~ S3全部是0,并且全体的偶校验是成功的,那么就说明此时没有发生错误
  • 如果S1~S3都不等于0。并且全体的偶校验失败,那么说明有移位的错误,我们只需要把它纠正就可以

1 ) 纠错场景1

  • 比如P1发生了跳变,那么最终我们S1~S3应该是001也就是指向了1这个位置
  • 由于P1这一个位发生了跳变就导致整体的偶校验失败的,此时H1这个位置发生了错误,我们只需要把它从1改为0就可以,不需要要求发送方重新发送这个数据

2 ) 纠错场景2

  • 如果说有两个位发生了错误,就像刚才那个例子一样,P1、P2同时发生了错误, 那么S1~S3得到的结果应该是011
    但这种情况下整体的偶校验是会成功的, 所以此时就说明是发生了两个比特位的错误,由于我们没有办法确定这两个比特位错在哪, 所以就需要要求对方重新传送这些数据

总结

概述

  • 在所有的数据校验方式当中海明码是比较难理解的,但是如果我们从它的基本思想出发就能更方便的理解为什么海明码这么设计
  • 本质上,它就是把所有的信息位进行分组,然后每一个组都进行偶校验,而每一个分组会对应一个校验位,所以如果有k个分组分组的话,自然就会有k个校验位
  • 对于海明码的求解,首先需要确定校验位的位数,接下来需要确定各个校验位还有信息位的分布
  • 那所有的这些校验位应该是分布在编号为1、2、4、8、16… 这些具有二进制位权重的位置
  • 我们可以把这些校验位的位置信息理解为某一种权重, 这些权重信息可以帮助我们记忆和理解
  • 当我们在进行分组的时候,这个分组规则是怎么制定的,每一个校验位所属的分组都应该确保他们拥有偶数的1
  • 再进行检错纠错的时候,我们就可以根据各个分组是否满足拥有偶数个1这样的条件来判断哪些分组出现了问题
  • 那根据各个分组偶校验的一个结果,我们就可以来判断到底是哪个位置出现了错误
  • 关于海明码的纠错和检错能力,为了区分到底是一位错还是两位错,我们通常还会在最高位加上一个全校验位,保证海明码的整体有偶数个1
  • 海明码这个知识点同时归属于计算机组成原理和计算机网络

结构树

  • 海明码
    • 基本思想
      • 分组偶校验,多个校验位可反应出错位置
    • 求解步骤
      • 确定校验位个数(k个校验位,n个信息位) 2 k ≥ n + k + 1 2^k \geq n+k+1 2kn+k+1
      • 确定校验位分布
        • P1、P2、P3 … 分别在 1, 2, 4, 8, 16 …
        • 空出来的其他位置一次填入信息位
      • 求校验位
        • 将信息位的位置序号用k位二进制数表示出来
        • 校验位 Pi 与 位置序号 第i位为1的信息位归为同一组, 进行偶校验
      • 纠错
        • 对P1,P2,P3…所属个分组进行异或(相当于分组偶校验), 求得 S1, S2, S3 …
        • S3S2S1 = 000 说明无错误
        • S3S2S1 ≠ \neq = 000, 则其值反应出错位置
    • 补充
      • 海明码有1位纠错,2位检错能力
      • 为了区分1位错还是2位错,还需添加"全校验位"对整体进行偶校验
      • 注意: 位置编号可能是从小到大的顺序,但是我们的处理方式雷同

http://chatgpt.dhexx.cn/article/xEMtnYiF.shtml

相关文章

海明码校验【简单详细】

海明码 1.什么是海明码: 一个名叫Richard Hanming老爷爷在1950年提出的检验纠错方法,它具有一位纠错能力。 2.海明码的计算方法: 设欲检测的二进制代码为n位,K为检测位(提供纠错),总共nk位代码 当中检测位满足的关系: 2 k 2^{k} 2k>(nk1) 此关系也是求不同代码长…

一文看懂海明校验码及其计算方法(详细总结)

网上看了好几篇文章后终于算是捋明白了,但是看到的这些资源要么说得云里雾里,要么干脆说得有问题(然后还被点了好多赞。。。),无论如何这些都容易误导小白。作为C站多年老潜水员,我还是把海明校验码的要点总…

ResNets

ResNets 背景: 非常非常深的神经网络是很难训练的,因为存在梯度消失和梯度爆炸问题。 《转载更改》 https://blog.csdn.net/qq_29893385/article/details/81207203 ResNets是由残差块(Residual block)构建的 首先解释一下什么是…

正确定位混淆后Crash代码行数

Android--定位混淆后Crash代码行数 一、需求背景二、前期准备三、对混淆日志进行还原四、示例 一、需求背景 打包时需要对代码进行混淆,目的是增加安全性,防⽌反编译。但这会导致App崩溃时,抓到的日志堆栈中显示的代码行数对应不上&#xff…

repalce

1、replace基本用法 <script>/*要求将字符串中所有的a全部用A代替*/var str "javascript is great script language!";//只会将第一个匹配到的a替换成Aconsole.log(str.replace("a", "A")); // > jAvascript is great script language…

Android studio 4.2新特性及升级异常

Android studio 版本及特性系列目录 Android 12 终于来了&#xff0c;你准备好了吗&#xff1f;Android studio 4.2新特性Android studio 4.1新特性Android Studio 4.0新特性及升级异常Android Studio3.6. 插件搜索不到终极解决方案 Android studio 4.2新特性 前言升级异常Gra…

强化学习的学习之路(五十一)2021-02-20 Retrace

作为一个新手&#xff0c;写这个强化学习-基础知识专栏是想和大家分享一下自己学习强化学习的学习历程&#xff0c;希望对大家能有所帮助。这个系列后面会不断更新&#xff0c;希望自己在2021年能保证平均每日一更的更新速度&#xff0c;主要是介绍强化学习的基础知识&#xff…

RecId

我记得好像AX最初版本RecId是所有表都唯一的。但是这样有一个坏处就是限制了数据库可存储的数据的条数。D365FO中RecId 不再全局唯一&#xff0c;但是表唯一。 每个表都有一个Sequences生成表的RecId,格式是&#xff1a;SEQ_TableId 右键Sequences可以看下当前RecId的值&#…

ResNet过程

#ResNet 因为网络传播的层次太深&#xff0c;后面的很难传播到前面&#xff0c;所以增加了一个短接层&#xff0c;深层次网络可以退化成一个浅层次网络 #filter_num 卷积核数量 #stride 步长 class BasicBlock(layers.Layer):def __init__(self,filter_num,stride1):super(Bas…

Android Stuido Proguard Retrace Unscrambler直接reProguard反混淆retrace日志

Android Stuido Proguard Retrace Unscrambler直接reProguard反混淆retrace日志 &#xff08;1&#xff09;如果Android Studio里面没有安装下列插件之一的&#xff0c;在Settings的Plugins里面安装其中一个&#xff1a; &#xff08;2&#xff09;菜单栏中的code里面找到反混…

android还原代码混淆proguard日志的工具--retrace和SmartRetrace

介绍 代码混淆时android反编译的常用方法&#xff0c;android SDK提供了Proguard工具&#xff0c;路径是 ANDROID_SDK_HOME/tools/proguard 命令行在ANDROID_SDK_HOME/tools/proguard/bin下&#xff0c;而实际的执行代码路径为ANDROID_SDK_HOME/tools/proguard/lib apk经过混…

with recursive用法

with recursive 则是一个递归的查询子句&#xff0c;他会把查询出来的结果再次代入到查询子句中继续查询。 with recursive d(n, fact) as ( values (1,2) union all #合并 select n1, (n1)*fact from d where n < 5) SELECT * from d;递归过程如下&#xff1a; n1 fact2 n…

python实验之绘制南丁格尔玫瑰图

一、实验目的 了解玫瑰图的前世今生&#xff1b;了解 matplotlib 标准库中的 pyplot 模块&#xff1b;了解在极坐标 系中绘制柱状图。 二、实验基本原理及步骤&#xff08;或方案设计及理论计算&#xff09; 实验步骤&#xff1a; 查阅文档&#xff0c;了解南丁格尔玫瑰图的原…

南丁格尔玫瑰图 | 集才华和美貌于一身的数据图表

南丁格尔玫瑰图将柱图转化为更美观的饼图形式&#xff0c;是极坐标化的柱图&#xff0c;其夸大了数据之间差异的视觉效果&#xff0c;适合展示数据原本差异小的数据。 1、玫瑰图的前世今生 长得像饼图又不是饼图&#xff0c;这种有着极坐标的统计图有着一个美丽的名字—南丁格…

雷达图+南丁格尔玫瑰图

具体实现的效果图&#xff1a; 使用的图表插件是echarts,具体的完整代码如下&#xff1a; import * as echarts from echarts;var chartDom document.getElementById(main); var myChart echarts.init(chartDom); var option;var arr [{ name: 1楼, value: 30 },{ name: 2楼…

Echarts南丁格尔玫瑰图、锥形柱状图、渐变曲线图

目录 1、南丁格尔玫瑰图 2、锥形柱状图 3、渐变曲线图 4、曲线图 1、南丁格尔玫瑰图 option {title: {text: 作物占比,left: 50, // 组件离容器左侧的距离top: 20},legend: {top: 52%,x: center,y: top,width: 180,height: 60,itemGap: 30,itemWidth: 15,itemHeight: 1…

Python数据可视化之南丁格尔玫瑰图(亲测)

文章目录 1. 什么是南丁格尔玫瑰图2. 南丁格尔玫瑰图的绘制 1. 什么是南丁格尔玫瑰图 央视新闻用来展示疫情0增长天数的图就是南丁格尔玫瑰图。 南丁格尔玫瑰图&#xff08;Nightingale rose diagram&#xff09;又名鸡冠花图、极坐标区域图。统计学家和医学改革家佛罗伦斯‧…

【R语言 南丁格尔玫瑰图绘制】

继续上一篇地理信息可视化讲起&#xff0c;为了能够更加直观的展示数据分布情况&#xff0c;发现之前人民日报客户端曾经做过一张关于疫情分布的玫瑰图&#xff0c;非常惊艳&#xff0c;故尝试用当前爬取的数据进行绘制。 绘图前数据整理 现存数据中不少地区病例已经清零&…

南丁格尔玫瑰图解析

一&#xff1a;先安装软件&#xff0c;任意一个都可以 PyCharm安装教程 https://www.cnblogs.com/du-hong/p/10244304.html Anaconda安装教程 https://blog.csdn.net/ITLearnHall/article/details/81708148 二&#xff1a;相关软件以及Python库的知识讲解&#xff1a; Py…

Echarts南丁格尔图.

项目场景&#xff1a; 通过Echarts修改南丁格尔图js文件&#xff0c;修改轮盘颜色。使项目更加美观 文本标签自定义 问题描述 不知道为什么自定义函数使饼图图形上的文本标签label标签显示在内部且&#xff0c;获得对应标签的数据。使用自定义函数formatter的参数是ar&#…