コンピューターサイエンス入門:理論編
単純チェックサム
この回でやること
バイトの和からチェックサムを求める仕組みを読み解き、一致しても見逃す変更を確かめます。
- 読む 約 7 分
- 最後にクイズ 1 問
ケーブルを流れる途中で1ビットが反転しても、受け取った側には普通のデータに見えます。壊れたことに気づく仕組みが要ります。軽い方法の1つが、全部足して1バイトに丸めた値を、一緒に送る方法です。
送る側と受け取る側で同じ計算をする
送る側が中身から短い値を計算して付け、受け取る側が同じ計算をして見比べます。この短い検査値をチェックサムと呼びます。ここではデータの各バイトを足し、256で割った余りを検査値にします。
違えばデータか検査値が変わったと分かり、送り直してもらえます。一致すれば検査を通りますが、中身が元と同じだと証明できるわけではありません。
現場ではシリアル通信などで、こうした軽い検査が使われます。バーコードの検査桁も似た目的ですが、計算規則は別です。ダウンロード後にSHA-256を照合するのも変更を検出するためですが、単純な和とは検出できる壊れ方が違います。
合計を256で割った余りにする
1バイトが表せるのは0から255です。合計が大きくなっても、この範囲に収めるために余りを取ります。Pythonでは % が余りの記号です。
Python
today = 3 # 曜日を0から6で表し、水曜を3とする
print((today + 10) % 7) # 6曜日は7日で一周するため、10日後は曜日番号6になります。同じように256で余りを取れば、結果は0から255です。たとえば合計が256なら0、257なら1になります。255を超えたら止める計算とは違います。
データの各値も0から255のバイトとして扱います。空のデータでは合計0なので、検査値も0です。負の数は今回の対象ではありません。
同じ値になる壊れ方がある
並び順が変わっても和は同じです。どこかが5増えて別の場所が5減っても、合計は変わりません。合計の差が256の倍数なら、余りを取ると差が消えます。
プレーンテキスト
[10, 60] の検査値は70
[60, 10] の検査値も70 並びが違っても同じ
[15, 55] の検査値も70 増減が打ち消し合うCRCなどは別の計算で、単純な和が見逃す誤りにも対応します。意図的な改ざんまで防ぐなら、検査値自体の信頼性も必要です。ハッシュをデータと一緒に書き換えられる状態では、ハッシュだけでも防げません。
例題で確かめる
送ったデータが [200, 100, 50] なら、合計350を256で割った余りは94です。検査値94を一緒に送ります。
受け取ったデータが [201, 99, 50] に変わっていたらどうでしょう。合計はやはり350で、検査値は94のままです。1増えた分と1減った分が打ち消し合うため、この変更は見逃します。一方、[201, 100, 50] なら合計351、検査値95となり、不一致を検出できます。