1. 程式人生 > >【海明碼】(容易看懂)

【海明碼】(容易看懂)

相加 htm 分析 log 遊戲 這也 還需 一個 包含

轉載自:http://www.cnblogs.com/scrutable/p/6052127.html

海明碼(也叫漢明碼)具有一位糾錯能力。本文以1010110這個二進制數為例解釋海明碼的編碼和校驗方法。

  編碼

  確定校驗碼的位數x

  設數據有n位,校驗碼有x位。則校驗碼一共有2x種取值方式。其中需要一種取值方式表示數據正確,剩下2x-1種取值方式表示有一位數據出錯。因為編碼後的二進制串有n+x位,因此x應該滿足

2x-1 ≥ n+x   

  使不等式成立的x的最小值就是校驗碼的位數。在本例中,n=7,解得x=4。

  確定校驗碼的位置

  校驗碼在二進制串中的位置為2的整數冪。剩下的位置為數據。如圖所示。

位置 1 2 3 4 5 6 7 8 9 10 11
內容 x1 x2 1 x3 0 1 0 x4 1 1 0

  求出校驗位的值

  以求x2的值為例。為了直觀,將表格中的位置用二進制表示。

位置 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011
內容 x1 x2 1 x3 0 1 0 x4 1 1 0

  為了求出x2,要使所有位置的第二位是1的數據(即形如**1*的位置的數據)的異或值為0。即x2^1^1^0^1^0 = 0。因此x2 = 1。

  同理可得x1 = 0, x3 = 1, x4 = 0。

位置 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011
內容 0 1 1 1 0 1 0 0 1 1 0

  因此1010110的海明碼為01110100110。

  校驗

  假設位置為1011的數據由0變成了1,校驗過程為:

  將所有位置形如***1, **1*, *1**, 1***的數據分別異或。

  ***1: 0^1^0^0^1^1 = 1

  **1*: 1^1^1^0^1^1 = 1

  *1**: 1^0^1^0 = 0

  1***: 0^1^1^1 = 1

  以上四組中,如果一組異或值為1,說明該組中有數據出錯了。***1 **1* 1***的異或都為1,說明出錯數據的位置為1011。

海明碼簡單分析

確定校驗位個數

海明碼的碼組長度需要符合:2^r – 1 (r代表校驗位個數)

為什麽是這個公式呢?因為:只有這樣才能保證校驗位足夠覆蓋整個需要校驗的碼組。

比如說:校驗位有3位,那就是2^3 = 8 – 1 = 7 這樣就可以校驗長度為7的碼組,如果按實際來說,也就是信息位 4 位,校驗碼 3 位。

通過上面分析,我們知道校驗位 r 加上信息位 k 就等於 2^r – 1 , 這也就是為什麽書上有 k + r <= 2^r – 1 的原因,下面是一些 R 和 K的關系表

信息碼位數12~45~1112~2627~5758~120
校驗碼位數 2 3 4 5 6 7

註:表中數據取自網絡

確定校驗位的位置

知道了需要多少位校驗碼,還需要知道把校驗碼放在哪個位置上才行,這個只要記住,信息位在非2n的位置上,而校驗位是在2n的位置上就可以了,條件再嚴格點就是,書上說的信息位所在海明碼中的下標是需要等於前面幾個校驗組的下標,看到這裏不懂沒有關系,下面進行簡單的例題分析。

舉個粟(例)子:

信息字碼組 : 1101 , 這時候信息位 k = 4 , 根據 k + r <= 2^r – 1 ,得出 r = 3 , 那就按書上說的,用P1、P2、P3來表示這3位校驗碼,這時候我們就來做填字格遊戲。

P1 P2 1 P3 1 0 1

位置就這麽簡單的確定下來了,如果位數更多的話也是一樣的,校驗位就是在 1、2、4、8、16…….這些位置上。

計算校驗位 Pi

上面已經知道要在什麽位置插入校驗碼,現在就差下鍋的料了,怎麽求校驗位實際的值呢?很簡單!

根據海明碼定義,是通過將信息進行分組,才得以實現檢錯和糾錯的能力,就像一開始的圖,每一個Pi都會包含3個信息位。

問題來了,那我怎麽知道這些信息位是哪幾個?還是書上的定義……

重點

比如說信息 1 1 0 1 ,從上面填字格遊戲我們可以看出,被分別安排在 H3,H5,H6,H7的位置(這些位置怎麽來的?7位數從1到7給每位編號嘛!)

則:H3 = H1+H2 (這裏是等式右邊下標相加等於等式左邊下標的意思,下面一樣)

H5 = H1+H4

H6 = H2 + H4

H7 = H1 + H2 + H4

通過上面的關系式,我們可以看出,右邊在海明碼中的數位,正好都是校驗碼的位置,下面來正式求校驗碼了。

P1(H1) = H3 ⊕ H5 ⊕ H7 (⊕表示異或)

P2(H2) = H3 ⊕ H6 ⊕ H7

P3(H4) = H5 ⊕ H6 ⊕ H7

大功告成!啥?還要我算出來?打字很累的,手短打字又慢,行吧行吧,想在以前自己學海明碼,怎麽看都不會的份上,可能也是自己太笨…….

信息碼:1101 對應海明位 H3、H5、H6、H7,不要把海明碼,校驗位,信息位搞混了哦!雖然我也是經常弄混哈哈!

P1 = 1 ⊕ 1 ⊕ 1 = 1;

P2 = 1 ⊕ 0 ⊕ 1 = 0;

P3 = 1 ⊕ 0 ⊕ 1 = 0;

啥?異或不懂?沒關系,我也經常不懂,相同 = 0 ,不同 = 1,異表示不同,按或的規則,是不是好奇葩!

好了,現在我們可以完成填字遊戲了 P1 P2 1 P3 1 0 1 ==> 1010101,這就是我們最後需要得到的海明碼,終於完成了!

還沒完呢……有了這個海明碼還需要知道怎麽校驗有沒有出錯啊,簡單簡單,跟我繼續來學習!

海明碼糾錯和檢錯

有了上面的校驗碼和信息碼,我們就能借用他們去知道怎麽檢查,信息在傳送的過程中有沒有發生錯誤,廢話不多說,下面開始,還是書上的定義,因為校驗碼有三位,我們這裏再申明三位碼分別用S1、S2、S3表示,滿足下列關系:

S1 = P1 ⊕ H3 ⊕ H5 ⊕ H7 ;

S2 = P2 ⊕ H3 ⊕ H6 ⊕ H7;

S3 = P3 ⊕ H5 ⊕ H6 ⊕ H7;

這樣求出來的S1、S2、S3如果都為0就是沒有出錯,如果不是0就表示在海明碼中出錯的位置,將其取反就可以起到糾錯的功能了。很簡單吧,等等,為什麽是上面的關系式?哪來的?可以往上看看求校驗碼那裏,這就是分組的結果,這裏我就偷懶下不算了,你們可以自己算算,真的結束了……

【海明碼】(容易看懂)