- 周五Java布置的实验写了一天,,,心好累
- 周六上午志愿者活动导致睡了一下午晚上又去看表演,,,心好累
- 后来发现我的C币涨了不少,,,惊讶,,,是因为我写的博客的原因吗?,,,开心~
- 错误检验与纠错确实是计算机在处理、存储和传输信息时非常重要的一部分。
- 就算计算机再强大,处理的数据都是错误的,那又有何用?
- 就算你再努力,方向是错的,到头来还不是一场空
- 就算是人算,也难免会出错。想起一个遥远的故事,那个算错了小数点而自杀提前去天堂占座的数学家,,,,,,不过似乎自杀的话去不了天堂?不太懂,,,,,,
- 所谓错误,就是对于计算机中的用1和0表示的二进制数据来说,某个或某些位在某种影响下改变了,比如原本的“0001”的第二位受到了某种神秘的影响,导致数据变成了“0011”,自然是很大的错误。
- 某种神秘的影响包括
- 电磁干扰,辐射,震动,,,,,,
- 设备的老化、损坏,,,,,,
奇偶校验码
- 分析一个问题最常见的思维就是从最简单的情况入手
- 奇偶检验码的原理:
- 多设置一个位(检验位)来记录一个二进制数据也就是一串01里面所包含的1的个数的奇偶性
- 根据不同的实现方式,分为奇检验和偶检验
- 奇检验Odd Parity
- 检验位为1,表示数据(不包含检验位)中1的个数为偶数个,加上检验位的话也就是由“奇数”个,正所谓奇检验
- 检验位为0,表示数据(不包含检验位)中1的个数为奇数个,本来就已经是奇数了,那就不需要检验位的帮忙了,检验位取0就好
- 偶检验Even Parity
- 和奇检验相对称。
- 怎么算?还记得神奇的异或运算吗?
- 两个数做异或运算
- 相同为0
- 不同为1
- 而n个数做异或运算
- 如果n个数中有奇数个1,则结果为1
- 如果n个数中有偶数个1,则结果为0
- 异或大法好,一下就可以得出奇偶性了。
- 两个数做异或运算
- 为啥这样规定?
- 直觉上我们想,奇检验的检验位为1,1表示真,也就是数据中“真的有奇数个1”
- 但是实际在编码的时候,检验位也属于数据啊!所以奇检验的检验位为1所表示的“真”的含义,就是所有的数据位包括检验位中1的个数为奇数个。
- 这样也方便计算机实现,而不需要单独把检验位挑出来,只需要事先规定好我们用的是奇检验还是偶检验就可以。
- 对于奇检验,我们把所有的数据包括检验位一起做XOR运算,如果结果为1则认为数据没出错,否则认为数据有误。
- 对于偶检验,一起做XOR的结果应当为0才认为数据没有出错。
- 然而奇偶检验只能发现“奇数个数据位的错误”,因为“奇数”才能影响原本的奇偶性
- 不过因为实现起来很简单,而且实际上占不小比例的错误都只是一个位的出错,所以奇偶检验应用很广泛
海明码
- 但毕竟奇偶检验的检验能力太低,而且只能“检验”而不能“纠错”,在数据的准确性要求更高的领域里,奇偶检验显然就不足以支撑台面了
- 格雷(Marcel Golay)于1949年、海明(Richar Hamming)于1950年分别独立设计了一种具备纠错能力的编码。后来被人们称为海明码。
- 基于信息编码理论的最小码距的概念,海明码的最小码距为3,具有检查并纠正一位错误,检测两位错误的能力。
- 最小码距:在一套编码系统中,任意一个合法的编码变成另外一个合法的编码所必须改变的最少的二进制位数。
- 如奇偶检验的最小码距为2,这是因为最少需要改变两个位就可以不改变原本1的个数的奇偶性,从而通过了奇偶检验。
细说海明码
- 海明码具有多个检验位,具体多少个还得根据原本数据的长度来算。
- 而且这多个检验位是和数据位混杂在一起的,不过也有规律可循就是了
- 编码位设置编号从1开始,分别记为B1、B2、B3……的话
- 检验位:所有编号为2^n的位为检验位,即B1、B2、B4、B8……为检验位,我们把检验位再单独排序称为C1、C2、C3、C4……
- 则有:Ci = B(2^i-1)
- 数据位:存放实际的数据,除检验位之外依次存放,单独编码为D1、D2、D3、D4…..
- 由于是二进制,实际上这种编码的方案在二进制下有更为显然的规律
- 检验位:所有编号为2^n的位为检验位,即B1、B2、B4、B8……为检验位,我们把检验位再单独排序称为C1、C2、C3、C4……
- 看表。我尤其喜欢MarkDown的语法,尤其是表格
编码位 | B1 | B2 | B3 | B4 | B5 | B6 | B7 | B8 | … |
---|---|---|---|---|---|---|---|---|---|
二进制编号 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | … |
对应含义 | P1 | P2 | D1 | P3 | D2 | D3 | D4 | P4 | … |
检验位 | P1 | P2 | P3 | P4 | … | ||||
数据位 | D1 | D2 | D3 | D4 | … |
- 很有美感的规律
- 检验位 Pi 对应的编码位为 Bj ,则有 j 的二进制编码有且仅有第i位为1
- P1,对应2^0=1,对应B1,即“0001”仅有第1位为1
- P2,对应2^1=2,对应B2,即“0010”仅有第2为为1
- P3,对应2^2=4,对应B4,即“0100”仅有第3位为1
- P4,对应2^3=8,对应B8,即“1000”仅有第4位为1
- 检验位 Pi 对应的编码位为 Bj ,则有 j 的二进制编码有且仅有第i位为1
海明码的编码方法
- 具体的编码方法
- 数据位D1、D2、D3、D4……即存放原始的数据
- 下面讲检验位要如何得到:
- 每个检验位所负责的数据位
- P1:B1、B3、B5、B7……
- P2:B2、B3、B6、B7……
- P3:B4、B5、B6、B7……
- P4:B8、B9、B10、B11……
- 看上面的大概是很难看出什么规律,不过我们把 Bj 的 j 写成二进制的话,那就有一个很美的规律了
- P1:B0001、B0011、B0101、B0111……
- P2:B0010、B0011、B0110、B0111……
- P3:B0100、B0101、B0110、B0111……
- P4:B1000、B1001、B1010、B1011……
- 当当当,规律就是
- Pi 所负责的所有的 Bj,其 j 的二进制编码的第 i 位都是1
- 也就是对于任意一个 Bj,如果 j 的二进制编码的第 i 位为1,则 Bj 就会由 Pi 负责。
- 显然,一个 Bj 有可能会有多位为1,那么这一位 Bj 自然也就对应着多个负责的检验位
- 对于检验位,由于检验位对应的 Bj 的 j 的二进制有且只有一位为1,所以检验位实际上必然只对自己负责
- 对于数据位,由于对应的 Bj 的 j 的二进制必然有2位以上为1(因为只有1位为1的必然是检验位),所以一个数据位至少被两个检验位所负责
- 规定好了每个检验位所负责的编码位了之后,那么检验位如何求呢?很简单,那就是奇偶检验
- 每个检验位所负责的数据位
编码位 | B1 | B2 | B3 | B4 | B5 | B6 | B7 | B8 | … |
---|---|---|---|---|---|---|---|---|---|
二进制编号 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | … |
对应含义 | P1 | P2 | D1 | P3 | D2 | D3 | D4 | P4 | … |
负责关系P1 | P1 | D1 | D2 | D4 | … | ||||
负责关系P2 | P2 | D1 | D3 | D4 | … | ||||
负责关系P3 | P3 | D2 | D3 | D4 | … | ||||
负责关系P4 | P4 | … |
海明码的使用方法
- 那么我们如何来看待这种美感规律之下的编码呢?即这种编码方案下如何检验错误与纠错呢?
- 我们说海明码具有1位的检验与纠错能力,和2位的检验能力
- 对于1位的出错
- 若为检验位,则该检验位所对应的一个负责关系将通不过奇偶检验
- 若为数据位,则该数据位对应的多个负责关系将通不过奇偶检验
- 那么对于所有的负责关系,我们按照其负责的检验位的顺序来生成一个二进制数字,即如果 Pi 所在的负责关系通不过奇偶检验,则该生成的二进制数字的第 i 位记为1,否则记为0
- 神奇的事发生了。我们最后得出来的数字,刚刚好就是出错的那一位
- 如果是检验位出错,而我们规定检验位 Pi 的位置是 B(2^i-1),即 Pi 所在的位置 Bj ,其 j 的二进制编码有且仅有第 i 位为1,也就是说 Pi 出了错,而 Pi 的位置刚好是“二进制编码有且仅有第 i 位为1”的位置。对应关系岂不妙哉
- 如果是数据位出错,而我们发现数据位的编码位 Bj,其 j总是含有多个为1的位,对于每一个第 i 位为1都对应了一个 Pi,那么在检验的时候,必然导致这多个负责关系 Pi 通不过奇偶检验,进而生成的二进制数字的编码则如同“光路可逆”一般,正好讲每一个第 i 位都设置成了1,也就刚好得出了出错的数据位的位置。更妙更妙。
- 就此而言,海明码是我所见过的对二进制规则运用最妙的结构之一。
- 对于2位出错,仍按上述规则来生成最后的数字,但是此时无法判断出是哪一位出错,但生成是数字总不是0。
- 反证法。如果两位出错而生成的数字为0。记Bx和By出错
- 1、若 Bx 为检验位,设 Bx 对应的检验位为 Pi,由于最后的数字为0,这就要求负责关系 Pi 能通过奇偶检验,而奇偶检验的最小码距为2,Pi 本身已经出错了,所以负责关系 Pi 中必然还有一个编码为要出错,而这一位只可能是数据位,即By只能为数据位。By若为数据位,则 By 必然对应两个以上的负责关系,除了负责关系Pi 外,设第二个为负责关系 Pj,则负责关系 Pj 有且只有 By 对应的数据位出错,所以负责关系 Pj 必然通不过奇偶检验,所以生成的数字必然不是0。矛盾。
- 2、若 Bx 和 By 均为检验位,由1的分析可知不可能。如果假设Bx和By均为检验位的话,那么分别对应了两个负责关系 Pi 和 Pj,则生成的数字必然不是0。
- 3、若 Bx 和 By 均为数据位,则 Bx 和 By 必然分别对应着两个以上的负责关系。由于每个负责关系均为奇偶检验,最小码距为2,这也就要求所有被 Bx 和 By 涉及到的负责关系都需要同时包含 Bx 和 By 才能保证通过奇偶检验,所以 Bx 和 By 就必然是同一个编码位。矛盾。
- 对于3位以上的出错,生成的数字就有可能是0了。这和数据无误的最后生成的数字相同。如B3、B5和B6。也就是说我们最少需要改变三位,就可以得到另一个在海明码规则下合法的编码了。所以最小码距为3。
- 实际使用的时候
- 对于常见的1位出错,如果我们发现的是检验位出错,但实际是检验位出错并不会影响数据位,也就是说实际的数据无误,则实际上并不影响数据的传输,可以无须纠正。
- 对于2位出错,我们只能判断“出错了”。然而实际上我们也无法确定这究竟是一位的出错还是两位的出错。
- 如果对精度要求不是那么高的话,一般会默认出错都是1位出错,并根据是否是检验位来判断是否需要纠正。
- 如果要求高的话,那么“一旦出错”,则会要求重新发送数据。
- 对于3位及以上的错,部分是可以被检验出出错来的,只有较少数情况下,而且这种情况发生的概率也是十分小的,才会“混过了海明码检验”。
循环冗余校验码
- CRC码。Cyclic Redundancy Check。
- 数据通信领域中最常用的一种查错校验码
- 信息字段和校验字段的长度可以任意选定,相对于海明码那种硬性的结构规定,因为运用了更为灵活的数学知识,所以CRC在长度方面极具灵活性
- 因为不在考试范围之内,虽然我也凭着兴趣研究了一番,然而在过程中极为痛苦,虽然用到了很多数学名词,然而并没有让我感受到数学的美,所以也就不打算在这里讲来让大家看得痛苦了让我自己也难受了……
- 有兴趣的可以自行谷歌百度。
Internet Checksum
- 查询相关内容的时候又发现的一种编码。
- 不做介绍只记录下来有这样一种方法就成
- 以后如果翻到这篇笔记的话,若仍有兴致,可自行谷歌百度
- 感觉这篇博客有点水,,,,,,不过我主要是想讲海明码,而又没有合适的配套讲的东西
- 之后我想整理一下编码,如ASCII、Unicode、UFT,,,这又不只是课本上的一两页了。。。比较麻烦而且考试还不考,,不过个人很感兴趣就是了。
- 之后会讲内容比较多的处理器,以及指令流的概念、优化、调度算法等等,怕是超出了计算机组成原理的范围,因为我也想讲讲计算机体系结构里的内容,尤其是指令的动态调度算法。
时间: 2024-10-05 05:11:38