汉明码(海明码)解析

news2025/1/12 15:57:42

文章目录

  • 前言
  • 启发
  • 汉明码介绍
  • 怎么实现汉明码?
  • 怎么实现更高模块的汉明码?
  • 为什么校验位一定是2的n次方?
  • 用更简洁的方式理解汉明码

前言

相信使用过光盘的读者都会有这样一种经历,如果不小心刮花了盘面,大部分情况下,把它放进DVD机器却仍然可以播放视频,这是为什么呢?

因为光盘的存储原理是同一份内容(二进制)存储三份,当进行播放的时候,会对三份内容进行位校验,按照少数服从多数原则进行 查错或者校订

什么意思呢?假设光盘存储的内容为:10101100110001,那么实际光盘会有三份这样的内容,假设我们在光盘某个位置刮花了,即二进制数据可能被修改了,那么当进行播放前,会将三份内容按照下面规则进行排列检验:
在这里插入图片描述

但是这样就会比较浪费存储空间,因为要存储一份内容,却要多花两倍空间,那怎么解决呢?

这就是本文将要引入的汉明码问题解析;

它所需要的检验错误的空间,只占整个内容的非常小一部分,它怎么实现的呢?我们慢慢道来

启发

在汉明发明汉明码之前,他知道存在一种奇偶检验算法,原理很简单,以16个数字块举例,第一个位置的值取决于后面15个位置中所有1的数量的奇偶,如果为奇数,那么第一个位置存储1,相反,存储0;(即保证16个块的所有1加起来为偶数,称为偶校验,相反的如果想加起来为奇数,则称为奇校验,我们这里只看偶检验)

在这里插入图片描述

如果我们发送这样一种含有16个bit的01信息,我们便只需要检查1的数量是否为偶数,如果为偶数,则说明信息未变化,否则说明变化了;

比如第一个矩阵块的第三行,第三列的0变为了1,那么1的数量就会变成奇数,接收方就可以知道数据发生了改变;

有人会说:如果改变了两个位置呢?即可能多生出了两个1,或者减少了两个1,那不就没办法了吗?

是这样的,但是即使现在这么多高深的算法,也无法保证所有信息都能100%正确,我们只是在概率上相对保证了而已,今天我们介绍的这个算法也是这样,他只能校验奇数数量的改变的正确性;

此算法完美的将任何一个比特位发生的错误,都反映在了第一个比特位上,但是此算法存在一个问题—无法知道是哪个比特位发生了错误

汉明码介绍

于是汉明想出了以个方法,他将16个块进行了分组,然后在分组上进行偶校验,对于为啥在特定位置设置为校验位,最后会讲,大家可以把疑惑放一下:
在这里插入图片描述

什么意思呢?

我们第一次先对位置全是奇数列的块进行分组,然后对1位置利用偶检验算法(即该位置的值取决于其他绿色区的所有1数量,如果相加为奇数,就需要该位置为1,保证所有绿色位置的1数量为偶数,相反,该位置填0)
在这里插入图片描述

假设左边图绿色区域位置有一个位置的值修改了,即0变1,或者1变0,那么经过检验就会知道绿色区的1数量为奇数,所以可以判定错误发生在右边图绿色(其实就是左边图绿色)区域位置,相反,如果1数量为偶数,则可以说明发生错误位置在右边灰色区域位置(或者没有发生错误,但是先不考虑这个,后面会有介绍)


第二次是对右边一半的列进行分组,然后对2位置进行偶检验算法:

在这里插入图片描述

假设左边绿色区域位置有一个位置的值修改了,即0变1,或者1变0,那么经过检验就会知道绿色区的1数量为奇数,所以可以判定错误发生在右边图绿色区域位置,相反,如果1数量为偶数,则可以说明发生错误位置在右边灰色区域位置(或者没有发生错误,但是先不考虑这个,后面会有介绍)

好了,说到这里,我们仔细观察上面右边四个小图,是不是能发现,任意一个位置,发生错误,我们都可以通过求交集,确定错误发生的位置

精确在哪一列

比如,第9个位置的比特位发生了变化,1变成了0:

  • 那么第一个分组可以检验到绿色区1的数量为奇数,从而确定发生错误的位置在第一个分组图的绿色区域位置;

  • 那么第二个分组可以检验到绿色区1的数量为偶数,从而确定发生错误的位置在第二个分组图的灰色区域位置;

  • 通过这两个图的交集,能够确定,发生错误的位置一定在第二列

    在这里插入图片描述

通过前面两个分组,你是不是有了启发,通过相同的方式进而确定发生错误的位置的行呢?是的,完全可以;

第三次分组,我们对第二行和第四行进行划分为一个小组,然后对4位置进行偶检验:
在这里插入图片描述

假设左边绿色区域位置有一个位置的值修改了,即0变1,或者1变0,那么经过检验就会知道绿色区的1数量为奇数,所以可以判定错误发生在右边图绿色区域位置,相反,如果1数量为偶数,则可以说明发生错误位置在右边灰色区域位置(或者没有发生错误,但是先不考虑这个,后面会有介绍)

第四次分组,我们对下半部分进行分组,然后对8位置进行偶检验:

在这里插入图片描述

假设左边绿色区域位置有一个位置的值修改了,即0变1,或者1变0,那么经过检验就会知道绿色区的1数量为奇数,所以可以判定错误发生在右边图绿色区域位置,相反,如果1数量为偶数,则可以说明发生错误位置在右边灰色区域位置(或者没有发生错误,但是先不考虑这个,后面会有介绍)

到这里,我们还是假设9位置发生了错误,1变成了0:

  • 那么第三个分组可以检验到绿色区1的数量为偶数,从而确定发生错误的位置在第三个分组图的灰色区域位置;
  • 那么第四个分组可以检验到绿色区1的数量为奇数,从而确定发生错误的位置在第事个分组图的绿色区域位置;
  • 通过这两个图的交集,能够确定,发生错误的位置一定在三行

在这里插入图片描述

通过一二分组,确定了错误发生在第二列,通过三四分组,确定了错误发生在第三行,也就是知道了错误发生在**[第二列,第三行]**位置,这样就完美且精确的确定了错误发生位置;

然后我们就可以将该位置的值改回去,这种算法比起之前的光盘算法来说,既节约了空间,又能精准定位位置,明显更优良

这里有个小问题:如果四个检验位(1,2,4,8位置),都没有检验出问题,即四次分组的绿色区域位置都是正常的,那只有两种可能

  • 发生错误的位置都是四次分组的灰色区域,即第0位置(可以根据我上面四种分组方法去求交集得到该结果,这里不再赘述)
  • 没有发生错误

也就是说,通过四个检验位,我们可以精确的确定发生错误的位置有16种可能性,且能精确定位出第[0-15]位置,但是没有发生错误这第17种可能性,我们却没办法解决,那怎么办呢?

答案是: 直接忽略第0位置,这样子当我们四个检验位都检查出来是偶数时候,说明数据正常,没有错误发生

当然,真正的大佬怎么可能会就这样浪费掉一个位置呢?他们把第0位置设置成了全局校验位,即它的值取决于除了它之外的所有位置的1的数量奇偶性,如果其他位置1数量之和为奇数,那么第0位置填1,相反填0,总之就是保证全局16个位置的1数量为偶数,我们称为全局偶校验;

这有什么作用呢?那就是我们可以监测出至少两个位置发送错误,比我们之前所说的局限性只能检验奇数变化多了一种可能性

比如第5号位置,和第9号位置都发生了错误:

  • 那么全局校验位为0
  • 同时通过另外四个校验位,我们可以找出第9号位置发生了错误

也就是说,当全局校验位为偶数,但是另外四个校验位检测出错误时候,表明至少有两个错误;因为如果只发生了一个变化,全局校验位应该为奇数

(注意哦,博主这里说的校验位为奇偶,不是指校验位(1,2,4,8)位置的值为1或者0,而是指它们所属的分组(绿色或者灰色)的所有位置加起来的1数量)

在我们日常生活中,无论要发生多少信息,都是把所有信息分为11个bit位为一组(因为第0位置,和另外四个校验位一共占据了5个位置),进行填充16块的矩阵,比如这里有信息: 00110001110,该怎么将它填入方框呢?答案如下:

在这里插入图片描述

现在,我们可以根据之前讲的四种分组分别对四个校验位进行填充,最后对全局校验位进行填充:

在这里插入图片描述

现在,假设你是发送方,你给对面发送了一个上面信息的数据块,但是数据传送过程中发生了错误,对面根据汉明码的检验,怎么进行确定发生错误并修改呢:

在这里插入图片描述

  • 第一个校验位为偶数(要记得之前博主提醒的不是说第1位置为0,而是之前说分组位置的所有1数量),说明发生错误的位置在第一列和第三列

  • 第二个校验位为奇数(因为有5个1),说明发生错误的位置在第三列和第四列

    通过第一和第二校验位,我们可以判定发生错误的位置在第三列

  • 第三个校验位为偶数 ,说明发生错误的位置在第一行和第三行

  • 第四个校验位为奇数,说明发生错误的位置在第三行和第四行

    通过第三和第四校验位,我们可以判定发生错误的位置在第三行

  • 通过四个校验位,我们知道了发生错误的位置在第三行第三列,即第10号位置

  • 全局校验位为奇数,那说明只有一个地方发生了错误,(毕竟三个,五个这种多奇数错误,我们也不知道,这种算法的默认前提就是只发生一个错误)

因此对面就可以更改第10位置,然后正确使用信息;

怎么实现汉明码?

为了实现汉明码,你可能会写一个算法,对可能发生错误的每一个位置进行检测,比如检测每个分组,然后记录结果,最后求交集,对吗?

是不是感觉非常繁琐呢?

但实际上,这却比你想象中的简单的多,我们以图中7号位置发生错误为例,那么第一分组,第二分组,第三分组的检验位都是奇数,而第四分组的检验位却为偶数.

我们把分组顺序按照第四,第三,第二,第一,这样排序,认为奇数检验结果为1,偶数检验结果0,那么可以得到这样结果0111,变成10进制就是7,而第7号为正好是发生错误的位置!!!

在这里插入图片描述

是不是感觉很神奇?因为:

在这里插入图片描述

换种说法,第7号位置发生错误,只影响了第一分组,第二分组和第三分组,而他们的校验位位置就是1,2,4;但是没有影响第四分组,所以8并没算进来

还不明白?那我们把0-15这16个位置编号转换为二进制,然后我们先看所有二进制最后一位为1的列,这刚好就是我们的第一分组,如果在这个分组上面发生了错误,就相当于在说:

  • 如果这里有错,是不是发生错误的位置,最后一个比特位为_ _ _ 1呢???(1代表检验位为奇数,发生了错误,上面说过)

在这里插入图片描述

我们在看倒数第二个比特位全是1的列,是否相当于在说:

  • 嘿,又是我,如果这里有错,是不是发生错误的位置,倒数第二个比特位为_ _ 1 _呢?

在这里插入图片描述

同样道理,我们在看倒数第三个比特位全是1的行,是否相当于在说:

  • 嘿嘿,还是我,如果这里有错,是不是发生错误的位置,倒数第三个比特位为_ 1 _ _呢?

在这里插入图片描述

最后,我们在看第一个比特位全为1的行,是否相当于在说:

  • 嘿嘿嘿,同样是我,如果这里有错,是不是发生错误的位置,倒数第三个比特位为0 _ _ _呢?(因为第四个分区校验位为偶数,代表没错,所以为0)

在这里插入图片描述

那我们把四次校验结果汇总,不就是像下面这样吗?

在这里插入图片描述

出现1比特位的物理位置刚好是第一分组,第二分组,和第三分组位置的交集,也就是第7位置,而第四分组并不包含第7位置,所以为0,

而0111转变为10进制后也就是7

怎么实现更高模块的汉明码?

通过上面的解释,想必我们也知道了为啥要这样进行分组

那么我们现在想要进行扩展,不适用16个块了呢?而是使用64个块呢?其实本质还是一样,我们照例把0-63位置变成二进制,然后根据对应比特位全是1和行或者列进行分组,比如第一个比特位全是1的行为一个分组:

至于其他更多可能性分组划分的罗列,这里就不做赘述了;

为什么校验位一定是2的n次方?

1,2,4,8,16等都是2的幂次方,如果把他们换算成二进制,是因为它们只有一个比特位为1,这意味着1,2,4,8等这种奇偶校验位有且仅有可能分别落在第一分组,第二分组,第三分组,第四分组等位置,而不可能落在其他分组

在这里插入图片描述

例如校验位4,它的二进制为0100,而它只可能属于倒数第三个比特位全1的行分组里面,而不会落在其他分组;

在这里插入图片描述

用更简洁的方式理解汉明码

如果说前面的方式都是在用巧妙的方式告诉我们错误位置的二进制表达,那我们可以用另一个角度进行看待: 异或

异或的特性是,相同为0,不同为1

  • 0 ^ 0 = 0;
  • 1 ^ 1 = 0;
  • 1 ^ 0 = 1;
  • 0 ^ 1 = 1;

换言之,异或结果就是对于待异或比特位奇偶校验位

现在我们根据这个特性,去看看怎么进行对汉明码求解错误位置,以下面图中10号位置出错(可以通过之前的分组方法求出来)为例:

在这里插入图片描述

我们把所有存储值为1的位置的编号转变为二进制进行异或:

在这里插入图片描述

得到的结果就是1010,换算成10进制就是10;

为什么呢,请看下图:

在这里插入图片描述

  • 我们只看最后一个比特位为1的值,它们刚好是第一分组位置存储值1的位置编号(3和15)
  • 再看倒数第二个比特位为1的值,它们刚好是第二分组位置存储1的位置编号(2,3,6,10和15)
  • 再看倒数第三个比特位为1的值,它们刚好是第三分组位置存储1的位置编号(4,6,12,15)
  • 同理,第一个比特位为1的值,它们刚好是第四分组位置存储1的位置编号(10,12,15)

而每一列的异或值,可以说是一个校验位,就类似于最上面介绍的那种方法,在问:

出错位置是不是在第一分组啊?_ _ _ 0,答: 不是

出错位置是不是在第二分组啊?_ _ 1 _, 答: 是

出错位置是不是在第三分组啊? _ 0 _ _,答: 不是

出错位置是不是在第四分组啊? 1 _ _ _,答: 是

将他们组合起来就是1010,意思是,不在第一分组,在第二分组,不在第三分组,在第四分组,用图求交集的话,就是下面这样:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/70728.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Tomcat打破双亲委派机制实现各应用程序的类库相互隔离原理与实现demo

1、实现原理 以Tomcat类加载为例,Tomcat 如果使用默认的双亲委派类加载机制行不行? 我们思考一下:Tomcat是个web容器, 那么它要解决什么问题: 1. 一个web容器可能需要部署两个应用程序,不同的应用程序可能会…

C++对const引用的特殊处理、为什么函数形参的引用建议加上const?只是为了防止值被修改吗?

前言:我们知道普通变量、指针、函数形参,加上const修饰表示不可改变,但是引用前面加上const就有特别之处了 目录 const日常使用 const引用的特别处理 const引用创建临时变量规则 引用形参声明为const的三个理由 const日常使用 我们知道如…

resnet(2)------看看卷积

文章目录1 . 人脑是怎么认识到物体的2. 卷积3. 卷积核1 . 人脑是怎么认识到物体的 在谈卷积之前,我们先来了解一下人是怎么认识物体的。 人脑是个非常复杂的结构,是由无数个神经元连接起来,每个神经元都有自己负责记忆的东西。当人眼看到物体…

关于自增约束auto_increment需要注意的地方,mysql8版本的报错

目录一,自增约束auto_increment需要注意的地方附:就算插入数据失败,也进行自增:二,自增约束auto_increment在MySQL8版本的报错:一,自增约束auto_increment需要注意的地方 1 创建数据库表class&…

Logistic回归

通常,Logistic回归用于二分类问题,例如预测明天是否会下雨。当然它也可以用于多分类问题. Logistic回归是分类方法,它利用的是Sigmoid函数阈值在[0,1]这个特性。Logistic回归进行分类的主要思想是:根据现有数据对分类边界线建立回…

啊?我这手速也太差了吧?——C++Easyx“挑战六秒”小游戏

🐑本文作者:C橙羊🐑 🎮🔊本文代码适合编译环境:DEV-C💻 ✨🧨温馨提示:此文转载于codebus🎉🎠 最近橙羊在Easyx官网的codebus里随便逛逛的时候&am…

SpringMVC从入门到精通(一)

文章目录1. SpringMVC基本概念1.1 三层架构1.2 MVC架构1.3 什么是SpringMVC1.4 SpringMVC的优势2. SpringMVC 的入门2.1 入门程序2.2 SpringMVC执行原理刨析2.3 SpringMVC的核心执行流程2.4 SpringMVC的组件3. RequestMapping注解4.请求参数绑定4.1 参数绑定4.2 请求参数乱码问…

磨金石摄影技能干货分享|优秀纪实摄影作品欣赏—北京记事

1、蜂窝煤 三名青年男子踏着三轮车拉着满满一车蜂窝煤。脸上流露出清澈的笑容。这是九十年代的北京,背后的天安门格外的显眼。那时候处于改革开放的初期,虽然还不是很富裕,但大家脸上洋溢着幸福与希望的笑容。 蜂窝煤是冬天必备,九…

【强化学习论文合集】十一.2018国际表征学习大会论文(ICLR2018)

强化学习(Reinforcement Learning, RL),又称再励学习、评价学习或增强学习,是机器学习的范式和方法论之一,用于描述和解决智能体(agent)在与环境的交互过程中通过学习策略以达成回报最大化或实现特定目标的问题。 本专栏整理了近几年国际顶级会议中,涉及强化学习(Rein…

历届青少年蓝桥杯python编程选拔赛 STEMA评测比赛真题解析【持续更新 已更新至34题】

蓝桥杯python选拔赛真题 历届青少年蓝桥杯python编程选拔赛真题解析 选拔赛 真题34-回文数升级 【蓝桥杯选拔赛真题34】python回文数升级 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析_小兔子编程的博客-CSDN博客python回文数升级2020年青少年组python蓝桥杯选拔赛真题一、…

剑指Offer39——数组中出现次数超过一半的数字

摘要 剑指Offer39 数组中出现次数超过一半的数字 本题常见的三种解法: 哈希表统计法: 遍历数组 nums ,用 HashMap 统计各数字的数量,即可找出 众数 。此方法时间和空间复杂度均为 O(N) 。数组排序法: 将数组 nums 排…

Python学习-8.1.1 标准库(time库的基础与实例)

2.1 time库 time库是Python提供的处理时间标准库。time库提供系统级精确计时器的计时功能,可以用来分析程序性能,也可以让程序暂停运行时间。 2.1.1 时间处理函数 time.time()函数:获取当前时间戳。 代表着如今的时间与1970年1月1日0分0秒…

18.10 字节码指令集与解析举例 - 同步控制指令

同步控制指令 组成 java虚拟机支持两种同步结构:方法级的同步和方法内部一段指令序列的同步,这两种同步都是使用monitor来支持的。 方法级的同步 方法级的同步:是隐式的,即无须通过字节码指令来控制,它实现在方法调…

Java+SSM网上书城全套含微信支付电商购物(含源码+论文+答辩PPT等)

项目功能简介: 本项目含代码详细讲解视频,手把手带同学们敲代码从0到1完成项目 该项目采用技术Springmvc、Spring、MyBatis、Tomcat服务器、MySQL数据库 项目含有源码、配套开发软件、软件安装教程、项目发布教程以及代码讲解教程 项目功能介绍: 系统管理…

HTML做一个简单的页面(纯html代码)地球专题学习网站

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

STM32F4 | 新建工程模板——寄存器版本 | HAL库入门 | 新建工程模板——库函数版本

文章目录一、新建工程模板——寄存器版本二、HAL入门1.固件库和寄存器的区别2.STM32CubeF43.HAL库包介绍三、新建HAL库工程模板一、新建工程模板——寄存器版本 开发环境:MDK5软件包:STM32CubeF4包 新建工程模板的一般步骤为: 新建工程目录&a…

【UE5】多用户协同编辑

UE5新出了一个多用户协同功能所以想搭一个来玩玩。 Epic已经将流程极度的简化了,在B站虚幻官方也放出了教程视频,[官方文档](多用户编辑入门 | 虚幻引擎文档 (unrealengine.com))也有教程。 这里做一下简要记录。 1.启用插件 首先打开Multi-User Edi…

SoftPerfect NetWorx中管理流量和宽带设备工具

SoftPerfect NetWorx中管理流量和宽带设备工具 NetWorx是用于在Windows中管理流量和宽带设备的简单工具和实用程序。如果我们利用交通设施,毫不拖延地利用教育系统,以及与各种驾驶员相关的学习,那么当加载互联网时,通过软件秘密使…

[附源码]计算机毕业设计酒店客房管理系统Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

BaiqiSoft MstHtmlEditor for .NET负责编辑的控制器

BaiqiSoft MstHtmlEditor for .NET负责编辑的控制器 BaiqiSoft MstHtmlEditor获取.NET for win表单被认为是一个元素,用户可以轻松灵活地将其融入到C#、VB.NET甚至WPF软件中。负责编辑的控制器,.NET Win Forms的MstHtmlEditor,允许用户和开发人员,甚至非技术用户使用该系列…