データのしくみをやさしく理解する
ハミング符号をゼロから理解する|たった1ビットの間違いを見つけて直す仕組み
保存した写真、送ったメッセージ、パソコンのメモリ。コンピューターの中では、すべてが「0」と「1」で扱われます。そのうち1個だけ数字が変わってしまったら? 実は、どこが間違ったかを計算で探して直す方法があります。
1. たった1個の0と1が変わると何が困る?
たとえば、スマートフォンで撮った写真を保存するとき、写真のデータは膨大な数の0と1に変換されます。データの保管や転送では、電子的なノイズや部品の不具合などが原因で、まれにビットが反転することがあります。
たとえば、こんなイメージ
保存した数字:1010101
読み出した数字:1000101
7つ並んだ数字のうち、左から3番目が「1 → 0」に変わっています。
数字を見比べられれば簡単です。でも実際には、読み出す側が元の正しい数字を知らないことがあります。そこで、データを保存する時点で「後から間違いを探すヒント」を一緒に付けます。それがハミング符号の発想です。
大事なのは、「正しい元データを別に丸ごと保存する」のではないこと。少しだけ追加情報を持たせて、異常の場所を見つけます。
2. 間違いを直すための「3人の見張り役」
7つの箱が並んでいると考えてください。全員を一度にチェックする係が1人いるだけでは、「何か変だ」と分かっても、どこが変なのか分かりません。
そこで、担当する箱が違う見張り役を3人用意します。ある箱が壊れたとき、どの見張り役が異常を報告するかという組合せで、間違った箱を特定できます。
| 見張り役 | チェックする箱 | 担当する箱の番号 |
| A(c₀) | 1・3・5・7番 | 1、3、5、7 |
| B(c₁) | 2・3・6・7番 | 2、3、6、7 |
| C(c₂) | 4・5・6・7番 | 4、5、6、7 |
たとえば3番の箱を見張っているのはAとBで、Cは見張っていません。だから、AとBだけが異常を発見すれば、3番が怪しいと分かるわけです。この「異常の出方」が、そのまま場所を表します。
3. 4ビットを7ビットで守る
ハミング(7,4)符号は、本当に保存したいデータ4ビットに、検査用の3ビットを追加して7ビットにする方式です。「(7,4)」は、完成形が7ビット、その中の情報が4ビットという意味です。
1番
検査
2番
検査
3番
データ
4番
検査
5番
データ
6番
データ
7番
データ
検査用ビットは1・2・4番に置きます。残る3・5・6・7番が実際のデータです。なぜこの配置なのかは、後で位置番号の仕組みを見ると分かります。
4. 最初に知っておく計算は「奇数か偶数か」だけ
難しい計算は不要です。「mod 2」は、合計を2で割った余り。つまり、1が偶数個なら0、奇数個なら1になります。これだけ覚えれば先へ進めます。
| 並んだ数字 | 1の個数 | 2で割った余り |
| 0、0、1、1 | 2個(偶数) | 0 |
| 1、0、1、1 | 3個(奇数) | 1 |
| 1、1、1、1 | 4個(偶数) | 0 |
プログラミングでは、この計算はXOR(排他的論理和)で実現できます。たとえば「1 XOR 1 = 0」「1 XOR 0 = 1」です。検査の結果が0なら偶数の約束を満たし、1なら約束が崩れています。
3人の見張り役はそれぞれ自分の担当範囲で、1が偶数個かどうかを確認しているのです。
5. 実際に1000101の間違いを探す
まず、壊れて届いたかもしれない7ビットを見てみましょう。左から順番に1〜7番です。
3人の見張り役の担当部分だけを取り出し、1の数が奇数か偶数かを調べます。
| 見張り役 | 担当する数字 | 1の数 | 結果 |
| A:1・3・5・7 | 1、0、1、1 | 3個(奇数) | c₀ = 1 |
| B:2・3・6・7 | 0、0、0、1 | 1個(奇数) | c₁ = 1 |
| C:4・5・6・7 | 0、1、0、1 | 2個(偶数) | c₂ = 0 |
つまり、AとBが「異常あり」、Cが「異常なし」。異常の組合せを数字に変換します。
異常の位置番号
1 × 1 + 1 × 2 + 0 × 4 = 3
左から3番目が間違っている
3番目を「0 → 1」にひっくり返すと、こうなります。
1000101 → 1010101。正しい数字を別に持っていなくても、1ビットだけの誤りなら、このように場所を求めて元に戻せます。
6. どうして「3番目」と分かるの?
実は、各番号を2進数で書くと、3人の担当割り当てが見えてきます。
| 位置 | 2進数(c₂ c₁ c₀) | 異常を報告する見張り役 |
| 1番 | 001 | A |
| 2番 | 010 | B |
| 3番 | 011 | A・B |
| 4番 | 100 | C |
| 5番 | 101 | A・C |
| 6番 | 110 | B・C |
| 7番 | 111 | A・B・C |
3番の2進数は011。AとBに対応する桁だけ1です。だから、検査結果が「c₂=0、c₁=1、c₀=1」になったとき、011(10進数で3)と読み取れます。
この3つの検査結果の組合せをシンドロームと呼びます。名前は難しくても、やっていることは「どの見張り役が異常を報告したかを番号に直す」だけです。
7. 7つのビットを触って壊して、直してみよう
ここまでの説明を、自分の手で確かめましょう。7個の数字のどれかをクリックすると、0と1が切り替わります。まずは「正しい状態」から1個だけ反転してみてください。見張り役A・B・Cの結果と、間違った位置がどう変化するか確認できます。
自分でデータを壊して、直してみる
正しいデータは 1010101。下の7つの数字を押すと、0と1がひっくり返ります。
オレンジ色は計算で「間違いの候補」と判定された場所。青色は選んだ見張り役の担当範囲です。
① どの見張り役が「異常あり」になる?
A・B・Cを押すと、その人が確認する箱が青く表示されます。
A(c₀)
1・3・5・7番を確認
1 + 0 + 1 + 1
結果:1(異常あり)
B(c₁)
2・3・6・7番を確認
0 + 0 + 0 + 1
結果:1(異常あり)
C(c₂)
4・5・6・7番を確認
0 + 1 + 0 + 1
結果:0(問題なし)
② 異常の組合せを番号に変える
1 × 1 + 1 × 2 + 0 × 4 = 3
左から3番目が間違っている、と推定します。
③ そこを反転したらどうなる?
1000101 → 1010101
1個だけ反転したので、正しい数字に戻せました。
これは仕組みを理解するための簡易モデルです。比較のために正解データを画面内に保持していますが、通常の受信側は正解を知りません。3ビット以上の誤りがある場合などは、検出されないこともあります。
次に、2個のビットを反転してみてください。数字上は訂正先が表示されますが、実際には元へ戻らないことがあります。ここがハミング符号の重要な限界です。
8. 直せるのは何個まで?
基本的なハミング(7,4)符号の能力は、1ビットの誤り訂正です。2ビットの誤りがあれば検査の異常は検出できますが、1ビット誤りと見分けられません。そのため、機械的に1ビット訂正すると、逆に誤った位置を書き換えてしまう場合があります。
| 元から変わった数 | 基本的な(7,4)符号で起こること | 注意 |
| 0個 | 異常なしと判定 | 通常はそのまま使用 |
| 1個 | 異常位置を特定して訂正 | 訂正できる |
| 2個 | 検査は異常を示す | 1個と区別できず誤訂正し得る |
| 3個以上 | 検出できない場合もある | 正しい復元は保証されない |
この違いは、ハミング距離で説明できます。ハミング距離は「2つのビット列で異なっている桁の数」です。基本の(7,4)符号では、正しい符号語同士の最小距離が3になるよう設計されています。最小距離3だから、1ビットを訂正でき、2ビットまでの誤りを検出できます。ただし、訂正処理だけで2ビット誤りだと判別できるわけではありません。
より安全にしたい場合は、全体のパリティビットをもう1つ足した拡張ハミング符号(SECDED)を使う方法があります。SECDEDは Single Error Correction, Double Error Detection の略で、1ビット訂正と2ビット検出を両立させる考え方です。
9. 実際にはどこで使われている?
身近な例はECCメモリです。サーバーなどで使われるメモリには、データに検査情報を付け、読み出し時にビット誤りを検出・訂正する仕組みが採用されることがあります。もちろん製品ごとに符号方式は異なるため、すべてのECCメモリがこの7ビットの方式を使うわけではありません。
データの伝送や保存では、再送によって回復する方法、チェックサムで異常を発見する方法、複数ビットまで訂正できる別の符号方式なども使われます。ハミング符号は、そのうち「少しの余分な情報を足して、読み出す側で間違いを直す」という考え方を理解するのに最適な例です。
10. よくある疑問
Q. どうして検査用の数字を3個追加するの?
0個の誤りと、1〜7番のどこか1個の誤りを区別するには、少なくとも8通りの状態が必要です。3ビットの検査結果には2³=8通りの組合せがあり、それぞれに対応できます。
Q. 元のデータが分からないのに、どうして直せるの?
元の4ビットをそのまま当てるのではなく、7ビット全体が満たす「偶数パリティ」の約束を使います。1個だけ反転したなら、約束が崩れるパターンから反転位置が一意に決まります。
Q. c₀・c₁・c₂がすべて0なら絶対に正しい?
いいえ。1ビットの誤りはありませんが、複数ビットの誤りが起きた場合には、検査結果がすべて0になることもあります。検査値0は「完全に正しいことの証明」ではありません。
Q. ビット列を左右逆に数えてもいい?
いいえ。この説明では左端を1番とする約束です。検査対象の位置もその約束に合わせているので、途中で数え方を変えると別の位置を訂正してしまいます。
11. 今日のまとめ
ハミング符号は、データに余分な検査ビットを足すことで、どこで0と1が入れ替わったかを計算できる仕組みです。
覚えておくのは、①4ビットの情報に3ビットの検査情報を足す、②3人の見張り役がそれぞれ担当位置を確認する、③異常の組合せを2進数の位置番号として読む、の3ステップ。
「1000101」なら検査値は 1・1・0。位置番号は 1 + 2 + 0 = 3。だから左から3番目をひっくり返して 1010101 に戻せます。この計算が理解できれば、ハミング符号の中心となる考え方はつかめています。