海明碼,又稱漢明碼,是一種線性糾錯碼,用於糾正數據。
奇偶校驗
我們常聽的數據校驗,莫過於奇偶校驗了。
假設數據傳過來01010101, 那么其中有1位作為校驗位,如果數據中包含有奇數個1的話,則將奇偶位設定為1;反之,如果數據中有偶數個1的話,則將奇偶位設定為0。
但是這個顯然只能知道出錯了,但是無法定位具體是哪一位出錯了,因此海明碼出現了!
海明碼
我們用更多的位,作為校驗位。
我們有一個公式(如果我們需要一次傳輸 n 位數據,那么這時候需要 k 為校驗位):2^k - 1 >= n + k
顯然,我們輸入 n,我們就能算出 k 的值。
舉個栗子
例如下圖,我們需要傳 15 位數據,套上公式(2^k - 1 >= 15 + k), 算出來 k 最小是 5 才滿足。
就是說這個時候,我們需要 5 為校驗位;包括數據和校驗位,總共會發出去 20 位。
標志位的位置
我們看到圖中,標綠的地方就是我們的校驗位,這些校驗位並不是從1號位排到5號位這么簡單,而是專門挑選 2^p 位來放置。
我們把標志位設為 p1、p2、p4、p8、p16
這是為了讓標志位能最大程度地表示出編號:p1 * 2^0 + p2 * 2^1 + p4 * 2^2 + p8 * 2^3 + p16 * 2^4,這 5 個校驗位的組合不同,不會出現重復的結果
如果直接把校驗位從1排到5,那就變成這樣:p1 * 2^0 + p2 * 2^1 + p4 * (2^0 + 2^1) + p8 * 2^2 + p16 * (2^0 + 2^2),這 5 個校驗位的組合不同會出現重復的結果
標志位的含義
既然 這 5 個校驗位各自表示着 1 個編號位,我們看下圖
p1 代表了 二進制編號中第一位為 1 的位(第1、3、5、7、9、11、13、15、17、19位)
p2 代表了 二進制編號中第二位為 1 的位(第2、3、6、7、10、11、14、15、18、19位)
.....
每一個校驗位 px 的值就是對代表的這些位(除掉其中的校驗位),進行異或的結果
p1 = d1 ⊕ d2 ⊕ d4 ⊕ d5 ⊕ d7 ⊕ d9 ⊕ d11 ⊕ d12 ⊕ d14
p2 = d1 ⊕ d3 ⊕ d4 ⊕ d6 ⊕ d7 ⊕ d10 ⊕ d11 ⊕ d13 ⊕ d14
...
至此,數據就已經准備好了,可以發送過來了。然而知道現在,我們的主角海明碼還沒出現 。莫急等我繼續說。
異或
我們知道異或,是2個2進制位的一種運算,相同取0,不相同取1。
再算一遍校驗位
我們客戶端接收到了上面 1 ~ 20 號的信息,用所有數據位再算一遍,按校驗位的策略再算一次校驗位,得到 p1'、p2'、p4'、p8'、p16'。
得到海明碼
s1 = p1' ⊕ p1
s2 = p2' ⊕ p2
s3 = p4' ⊕ p4
s4 = p8' ⊕ p8
s5 = p16' ⊕ p16
如果 s1 ~ s5 有出現非0,則表示有數據位出錯了。
而 s1 ~ s5 組成的編號,就是具體出錯的那個位了!!