チェックサム

チェックサム（検査合計、）とは、ワード列の各ワードの総和を利用した誤り検出符号の一種である。他の誤り検出符号と比べて信頼性は低いものの、単純計算で99.6%以上の検出率があるうえに計算が簡単であることから、簡易な誤り検出に用いられる。

名称・用語 
「チェックサム」という名称は、チェックサムの符号値そのものを指すこともある。

また、誤り検出その他データの検証のための符号として広く使われてきた経緯から、俗に誤り検出符号自体の代名詞としても用いられる場合がある。例えばCRCの符号値やMD5のハッシュ値を、それぞれ「CRCチェックサム」「MD5チェックサム」と呼ぶことがある。これらは算出方法が異なりsumでもないため、「チェックサム」と呼ぶことは語義的には正確ではないものの、「（チェックサムよりも）信頼性の高い誤り検出符号」程度の意味で使われる。

算出方法 
算出方法は非常に簡単で、もっとも単純なものはワード列の個々のワードの総和 (sum) の下位1ワードをそのまま符号値とするものであり、1ワードを何ビットとするかは実装によって異なる。

例えば、1ワードが8ビットの以下のワード列の総和は（十六進法で）78であるので、その検査合計は「78」となる。

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

総和のどのビット群を符号値とするか、符号値をどのように扱うかなどで、派生した種類がある。

ネットワークを利用してのデータ送信時、IPパケットにデータを分割した際のIPヘッダの検査における利用例を以下に示す。

 IPヘッダのチェックサム欄にゼロをセット
 IPヘッダを16ビット単位で加算
 総和の下位16ビットの補数をIPヘッダのチェックサム欄にセット
 送信
 受信したらIPヘッダを16ビット単位で加算
 総和がゼロならば正常
チェックサム欄にはチェックサム欄がゼロの場合におけるチェックサムの補数がセットされているので、総和 = チェックサム欄以外のチェックサム + チェックサム欄以外のチェックサムの補数 = ゼロ になれば正しい。

Intel HEXなどのROMデータの場合、8bit単位で加算して32bit表示を行う事が一般的である。例えば12 34 56 78場合のチェックサムは0x12+0x34+0x56+0x78=0x00000114となる。

バリエーション 
チェックサムの実装にはいくつかバリエーションが考えられる。以下にいくつか例を示すが、これらに限られない。

チェックサム欄に書き込む値 
チェックサム欄には、合計値をそのまま書く場合と、上記のIPヘッダの例のように補数を書き込む場合がある。
補数を書き込むようにすると、「チェックサム欄の値も含めて計算を行い、ゼロ（あるいはある特定の数値）になれば正常」という方法で検査ができる。このような設計では、受信側でデータの長さが事前に分からない場合でも、通信が終了するまで全部足し込んでしまえば良いので、検査を行うことができる。

初期値問題 
チェックサム欄を非ゼロ値で初期化してから加算を行う実装もある。この場合、0x00 .... 0x00 (すべてゼロ) というデータに対してチェックサムが非ゼロ値になる。言い換えるとデータとチェックサム欄を含めた全体がすべて 0x00 というのは、チェックサムが不正なデータとなる。なんらかの理由でデータを正常に読み出せず 0x00 を受信してしまった場合、チェックサム欄をゼロ初期化する実装では、これを正常なデータと区別がつかないが、非ゼロ初期化ならエラーとなる。

位置依存 

上記の単純なチェックサムでは、一般的な誤りを検出できないことがある。例えば、データワードの順序の変更、すべてのビットがゼロのワードの挿入・削除などである。実用的に使われているチェックサムアルゴリズム、例えば フレッチャーのチェックサム, Adler-32, and 巡回冗長検査 (CRCs) のようなものでは、各ワードの値だけでなく、シーケンス内での位置も考慮することで、これらの弱点に対処している。一般にこれらの特徴により、チェックサムの計算コストは増大する。

信頼性 
単純な加算であるため、ワードを保持したまま列の順序のみ変化した場合には同じ値を示す。また、それ以外の誤りに対しても、符号値が同じになる確率は決して低くなく、誤り検出の方式としての信頼性は高くない。

また、チェックサムをはじめとする誤り検出符号はハッシュ関数と異なり、暗号化や改ざん防止技術の用途は考慮されていない。そのため、偶発的な誤りに対する耐性を高めるだけであり、意図的な改竄（チェックサムは同じで異なる内容にする）に対する耐性はない。特にチェックサムは単純な加算であることから、同じ符号値になる異なる内容を探すことが容易である。例えば、前述の語列（→#算出方法）の前半後半を入れ替えた列「08 09 0A 0B 0C 0D 0E 0F 00 01 02 03 04 05 06 07」も、チェックサム値は同じ78である。

意図的な改竄の例 
元の語列を前述の「00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F」とする。

これとまったく別のワード列「70 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00」のチェックサム値は72であるが、最後のバイトを「00」から「06」にすれば元のワード列と同一のチェックサム「78」となる。こうして、意図的にチェックサムの整合性を取ることができる。もしも、ある一連の語列処理機構が受け取ったワード列の正当性をチェックサムでのみ保証していた場合、この機構はこの別のワード列を元のワード列として誤って認識してしまうことになる。

脚注

注釈

出典

関連項目 
 巡回冗長検査 (CRC)
 ハミング符号
 パリティ - パリティビット（パリティチェック）
 Adler-32
 Luhnアルゴリズム
 チェックディジット
 Dammアルゴリズム
 ヴァーヘフアルゴリズム

誤り検出訂正