在電信領域中，**漢明碼**（英語：），也称为**海明码**，是(7,4)汉明码（英语：）推广得到的一種线性纠错码，由理查德·衛斯里·漢明于1950年發明。相比而言，簡單的奇偶檢驗碼除了不能糾正錯誤之外，也只能偵測出奇數個的錯誤。汉明码是完备码（英语：），它在于它分组长度相同、最小距离为3的码中能达到最高的码率。

用數學术语来说，漢明碼是一種二元線性碼。對於所有整數 *r* ≥ 2，存在一个分组长度 *n* = 2*r* − 1、*k* = 2*r* − *r* − 1 编码。因此汉明码的码率为 *R* = *k* / *n* = 1 − *r* / (2*r* − 1)，对于最小距离为3、分组长度为 2*r* − 1 的码来说是最高的。漢明碼的奇偶檢驗矩陣的是通過列出所有长度为 *r* 的非零列向量构成的。

歷史
--

漢明碼的發明者理查德·衛斯里·漢明在1948年，運用貝爾模型V（Bell Model V）電腦於貝爾實驗室（Bell Labs）工作。輸入端是依靠打孔卡（Punched Card），這不免會造成些讀取錯誤。在工作日，當機器檢測到錯誤將停止並閃燈（flash lights），使得操作員能夠解決這個錯誤。在週末和下班期間，沒有操作者的情況下，機器只會簡單地轉移到下一個工作。

漢明在週末工作，他對於不可靠的讀卡機發生錯誤後，總是不得不重新啟動程序變得愈來愈沮喪。在接下来的幾年中，他为了解決偵錯的問題，開發了功能日益強大的偵錯演算法。在1950年，他發表了今日所稱的**漢明碼**，並且時至今日仍在修正錯誤記憶體上顯示其應用價值。

### 漢明碼之前

人們在漢明碼出現之前使用過多種檢查错誤的編碼方式，但是沒有一個可以在和漢明碼在相同空間消耗的情况下，得到相等的效果。

#### 奇偶

条目：奇偶校驗位
奇偶校验是一种添加一个奇偶位用来指示之前的数据中包含有奇数还是偶数个1的检验方式。如果在传输的过程中，有奇数个位发生了改变，那么这个错误将被检测出来（注意奇偶位本身也可能改变）。一般来说，如果数据中包含有**奇数个**1的话，则将奇偶位设定为**1**；反之，如果数据中有**偶数个**1的话，则将奇偶位设定为**0**。换句话说，原始数据和奇偶位组成的新数据中，将总共包含偶数个1.

奇偶校验并不總是有效，如果数据中有偶数个位发生变化，则奇偶位仍将是正确的，因此不能检测出错误。而且，即使奇偶校验检测出了错误，它也不能指出哪一位出现了错误，从而難以进行更正。数据必须整体丢弃并且重新传输。在一个噪音较大的媒介中，成功传输数据可能需要很长时间甚至不可能完成。虽然奇偶校验的效果不佳，但是由于他只需要一位额外的空间开销，因此这是开销最小的检测方式。并且，如果知道了发生错误的位，若将该位取反，奇偶校验还可以恢复数据。

#### 五取二代碼

五取二代碼使用由3個0和2個1組成的五個位，以此提供十種可能的組合來表示數字 0-9。 該方案可以檢測所有單比特錯誤、所有奇數位錯誤和一些偶數位錯誤（例如兩個 「1」位的翻轉）。 但是它無法自行糾正這些錯誤。

漢明碼
---

如果一條信息中包含更多用于纠错的位，且通过妥善安排这些纠错位使得不同的出错位产生不同的错误结果，那麼我們就可以找出出錯位了。在一个7位的信息中，单个位出错有7种可能，因此3个错误控制位就足以確定是否出錯及哪一位出錯了。

漢明研究了包括五取二碼在内的编碼方案，並歸納了他們的想法。

### 通用算法

下列通用算法可以为任意位数字产生一个可以纠错一位（英語：）的漢明碼。

1. 從1开始给數字的數據位（从左向右）标上序号, 1，2，3，4，5...
2. 将这些数据位的位置序号转换为二进制，1, 10, 11, 100, 101,等。
3. 数据位的位置序号中所有为二的幂次方的位（编号1，2，4，8，等，即数据位位置序号的二进制表示中只有一个1）是校验位
4. 所有其它位置的数据位（数据位位置序号的二进制表示中至少2个是1）是新的数据位
5. 每一位的数据包含在特定的两个或两个以上的校验位中，这些校验位取决于这些数据位的位置数值的二进制表示
	1. 校验位1覆盖了所有数据位位置序號的二進制表示倒数第一位是1的数据：1（校验位自身，这里都是二进制，下同），11，101，111，1001，等
	2. 校验位2覆盖了所有数据位位置序号的二进制表示倒数第二位是1的数据：10（校验位自身），11，110，111，1010，1011，等
	3. 校验位4覆盖了所有数据位位置序号的二进制表示倒数第三位是1的数据：100（校验位自身），101，110，111，1100，1101，1110，1111，等
	4. 校验位8覆盖了所有数据位位置序号的二进制表示倒数第四位是1的数据：1000（校验位自身），1001，1010，1011，1100，1101，1110，1111，等
	5. 简而言之，所有校验位覆盖了数据位置和该校验位位置的二进制与的值不为0的数。

采用奇校验还是偶校验都是可行的。偶校验从数学的角度看更简单一些，但在实践中并没有区别。

校验位一般的规律可以如下表示：

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 数据位位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | ... |
| 编码后数据位置 | p1 | p2 | d1 | p4 | d2 | d3 | d4 | p8 | d5 | d6 | d7 | d8 | d9 | d10 | d11 | p16 | d12 | d13 | d14 | d15 |
| 奇偶校驗位覆蓋率 | p1 | X |  | X |  | X |  | X |  | X |  | X |  | X |  | X |  | X |  | X |  |
| p2 |  | X | X |  |  | X | X |  |  | X | X |  |  | X | X |  |  | X | X |  |
| p4 |  |  |  | X | X | X | X |  |  |  |  | X | X | X | X |  |  |  |  | X |
| p8 |  |  |  |  |  |  |  | X | X | X | X | X | X | X | X |  |  |  |  |  |
| p16 |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  | X | X | X | X | X |

表中只给出了20个编码后的位（5个奇偶校验位，15个数据位）。观察上表可发现一个比较直观的规律：第i个检验位是第2i-1位，从该位开始，检验2i-1位，跳过2i-1位……依次类推。例如上表中第3个检验位p4从第23-1=4位开始，检验4、5、6、7共4位，然后跳过8、9、10、11共4位，再检验12、13、14、15共4位……

要检查某一位的错误，则需检查某一位所包含的所有奇偶校验位。这种错误的模式被叫做伴随式错误。如果所有奇偶校验位是正确的，就没有错误。除此以外的情况，错误的奇偶校验位的位置的和将识别错误的位。例如，如果位置为1、2、8的奇偶校验位指示了一个错误，那么位置为1+2+8=11的位出错了。如果只有一个奇偶校验位指示了错误，那么该奇偶校验位自身出错了。

### 例子

对11000010进行汉明编码，求编码后的码字。

1.列出表格，从左往右（或从右往左）填入数字，但2的次方的位置不填。

|  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 数据 |  |  | 1 |  | 1 | 0 | 0 |  | 0 | 0 | 1 | 0 |

2.把**数据**行有1的列的**位置**写为二进制。

|  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 数据 |  |  | 1 |  | 1 | 0 | 0 |  | 0 | 0 | 1 | 0 |
| 二进制 |  |  | 0011 |  | 0101 |  |  |  |  |  | 1011 |  |

3.收集所有二进制数字，求异或。0011\oplus 0101\oplus 1011=1101

4.把1101依次填入表格中2的次方的位置（低位在左）。

|  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 位置 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 数据 |  |  | 1 |  | 1 | 0 | 0 |  | 0 | 0 | 1 | 0 |
| 二进制 |  |  | 0011 |  | 0101 |  |  |  |  |  | 1011 |  |
| 校验 | 1 | 0 |  | 1 |  |  |  | 1 |  |  |  |  |

5.所以编码后的码字是101110010010。

带附加奇偶校验码的汉明码（SECDED）
--------------------

加一個位元在數列的最前面，採用奇校验码或偶校验码， 用以檢驗後面的汉明码是否有錯。

(7,4)漢明碼
--------

Graphical depiction of the 4 data bits and 3 parity bits and which parity bits apply to which data bits
条目：(7,4)漢明碼
1950年，漢明发明了(7,4)代碼。其編碼由4資料位元到7位，增加三個奇偶校驗碼。(7,4)漢明碼可以檢測並糾正單位元錯誤，且也能檢測雙位元錯誤。

建立奇偶檢驗矩陣
--------

矩陣{\mathbf {G}}:={\begin{pmatrix}I\_{k}|-A^{T}\\\end{pmatrix}}被稱為（標準）生成矩陣線性(n,k)碼。

和{\mathbf {H}}:={\begin{pmatrix}A|I\_{{n-k}}\\\end{pmatrix}}被稱為奇偶檢驗矩陣。

編碼
--

範例

从上述矩阵我们有2k=24=16码词。

二进制码\overrightarrow {x}的码词可以从\overrightarrow {x}=\overrightarrow {a}G得到。对\overrightarrow {a}=a\_{1}a\_{2}a\_{3}a\_{4}和a\_{i}存在F\_{2}(一个只有0和1的二元域）。

故此码表即是所有4个三元组（k个三元组）。

因而，（1,0,1,1）编码为（*0*,*1*,1,0,*0*,1,1）。

(8,4)漢明碼
--------

The same (7,4) example from above with an extra parity bit
(7,4)汉明码可以很容易地编码为一个(8,4)码，通过在(7,4)编码词（*参见(7,4)汉明码*）上附加一个额外的奇偶位。

这可以用下面修正的矩阵相加：

{\mathbf {G}}:={\begin{pmatrix}1&1&1&0&0&0&0&1\\1&0&0&1&1&0&0&1\\0&1&0&1&0&1&0&1\\1&1&0&1&0&0&1&0\end{pmatrix}}\_{{8,4}}
和

{\mathbf {H}}:={\begin{pmatrix}1&0&1&0&1&0&1&0\\0&1&1&0&0&1&1&0\\0&0&0&1&1&1&1&0\\1&1&1&1&1&1&1&1\end{pmatrix}}\_{{4,8}}。
注意，\mathbf{H}并非用标准形式表示。为了得到{\mathbf {G}}，原子行操作能够被用来获得一个等价的矩阵对陈形式的\mathbf{H}：

{\mathbf {H}}=\left(\left.{\begin{array}{cccc}0&1&1&1\\1&0&1&1\\1&1&0&1\\1&1&1&0\end{array}}\right|{\begin{array}{cccc}1&0&0&0\\0&1&0&0\\0&0&1&0\\0&0&0&1\end{array}}\right)\_{{4,8}}。

(11,7)漢明碼
---------

相關條目
----

* 格雷碼
* 漢明距離
* 前向錯誤更正
* 里德-所罗门码

參考文獻
----

* Moon, Todd K.. New Jersey: John Wiley & Sons. 2005  [2009-06-18]. ISBN 978-0-471-64800-0. （原始内容存档于2008-04-06）.
* MacKay, David J.C.. Cambridge: Cambridge University Press. 2003-09. ISBN 0-521-64298-1. （原始内容存档于2016-02-17）.
* D.K. Bhattacharryya, S. Nandi.. : 410–415. doi:10.1109/ISPAN.1997.645128.

外部連結
----

* CGI script for calculating Hamming distances（from R. Tervo, UNB, Canada） （页面存档备份，存于）

1. ↑   (PDF).  [2016-09-01]. （原始内容存档 (PDF)于2021-04-17）.