単純チェックサム

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

単純チェックサム

このレッスンで分かること

  • mod 256 を取らずに合計だけ返す実装もありますが、1 バイトに収める のが「単純チェックサム」の定義としては一般的です
  • ネットワークやストレージで「データが途中で化けていないか」を検知するために使われるのが チェックサム です
  • ファイルをダウンロードしたあとに MD5SHA-256 の値を比べた経験があるかもしれません

単純チェックサム とは

バイト配列の各要素を 256 (1 バイト) の範囲で足し合わせ、単純なチェックサムを計算します。本レッスンでは、単純チェックサム の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

ネットワークやストレージで「データが途中で化けていないか」を検知するために使われるのが チェックサム です。本レッスンでは、バイト配列の合計を 256 で剰余を取る最もシンプルなチェックサムを実装します。

チェックサムの役割

ファイルをダウンロードしたあとに MD5SHA-256 の値を比べた経験があるかもしれません。これは「同じビット列か」を素早く確認する仕組みで、ハッシュ系のチェックサムです。今回扱うのは、もっと単純で軽量な 8bit チェックサム です。

  • 計算が O(n) で速い
  • 値域が 0255 の 1 バイトに収まる
  • 衝突しやすいが、シリアル通信バーコードUART のような単純なプロトコルで広く使われる

例えば IPv4 ヘッダのチェックサム、Modbus の LRC、バーコード のチェックディジット、クレジットカード番号 の Luhn アルゴリズムなど、用途は多岐にわたります。

計算式

バイト配列 bytes のチェックサムは次の式で求まります。

checksum = (b0 + b1 + ... + bn-1) mod 256

つまり全部足して 256 で割った余りです。1 バイトの範囲 (0255) に収めるための剰余演算 (% 256) がポイントです。

diagram (will load when visible)

図のポイント (テキスト併記)

  • mod 256 を取らずに合計だけ返す実装もありますが、1 バイトに収める のが「単純チェックサム」の定義としては一般的です

mod 256 を取らずに合計だけ返す実装もありますが、1 バイトに収める のが「単純チェックサム」の定義としては一般的です。

具体例

  • [] (空配列) → 0
  • [0]0
  • [1, 2, 3]6
  • [100, 100, 100]300 % 256 = 44
  • [255, 1]256 % 256 = 0
  • [255, 255, 255, 255]1020 % 256 = 252

5 番目の例で [255, 1] のチェックサムが 0 になるのは、わざと足して 256 ぴったりになる組み合わせを選んだからです。実データではこれが「衝突」の典型例です。

Python 実装

Python

def checksumSum(bytes_list): total = 0 for b in bytes_list: total += b return total % 256

sum(bytes_list) % 256 の 1 行でも書けますが、ループ版のほうが他言語との対応がわかりやすいです。bytes という変数名は Python の組み込みと衝突するので、bytes_list のように別名にしています。

JavaScript 実装

JavaScript

function checksumSum(bytes) { let total = 0; for (const b of bytes) total += b; return total % 256; }

Array.prototype.reduce を使えば bytes.reduce((a, b) => a + b, 0) % 256 の 1 行で書けます。可読性の好みで選んでください。

より高度なチェックサム

単純チェックサムには弱点があります。[1, 2][2, 1] のチェックサムは同じ 3 になり、並び順の入れ替え を検知できません。これを解決するために、実用的なプロトコルでは次の改良版が使われます。

  • CRC-32 (Cyclic Redundancy Check) — 32bit の値で、ビット反転やバースト誤りの検出力が高い
  • Fletcher / Adler-32 — 順序を考慮した軽量チェックサム
  • MD5 / SHA-1 / SHA-256 — 暗号学的ハッシュ、衝突確率が極めて低い

通信路の信頼度が低い場合は CRC-32 以上、改ざん検知が目的なら SHA-256 以上を使うのが現代の定石です。単純チェックサム は学習用と理解しておきましょう。

送信側と受信側

プロトコル設計では、送信側がチェックサムをデータの末尾に付け、受信側が自分で再計算して比較する、という流れが一般的です。一致しなければ「壊れた」と判断して 再送要求 を出します。チェックサムは「同じか違うか」しか教えてくれない一方向の検査ですが、再送 という素朴な仕組みと組み合わせるだけで信頼性のあるプロトコルが構築できます。

また、チェックサム自身もデータの一部とみなして「全体のチェックサムが 0 になる」ように設計するテクニックもよく使われます。IPv4 ヘッダのチェックサムフィールドもこの考え方(チェックサム込みで検算する)を採用していますが、方式は16bitの1の補数和であり、単純な mod 256 の加算とは異なります。

よくある間違い

  • % 256 を忘れ、値が 1024 のような 1 バイトを超えた値を返す
  • 空配列のときに total を初期化せず、エラーになる
  • バイト値が 0255 の範囲外 (負数や 256 以上) でも受け付けて、剰余が正しく出ない
  • bytes という変数名を Python の組み込み型と衝突させてしまう
  • 浮動小数点の足し算になってしまい、% の結果が小数になる

やってみよう

関数 checksumSum(bytes) を実装してください。bytes はバイト値 (0255 の整数) の配列で、合計を 256 で割った余りを整数で返します。空配列のときは 0 を返します。

よくある質問

Q. このトピックを覚える意味は何ですか?

A. チェックサムは「データが途中で化けていないか」を軽量に検知する仕組みです。TCP/IPヘッダーやファイル転送プロトコルなど、あらゆる通信・保存の基盤で使われている考え方なので、仕組みを一度理解しておくと、より高度なハッシュ関数(MD5, SHA-256)の理解にも繋がります。

Q. 実務でこの知識を使う場面は?

A. ファイルダウンロード後の整合性検証、ネットワークパケットのエラー検出、シリアル通信でのデータ破損チェックなど、軽量な破損検出が必要な場面で使われます。より強固な改ざん検知が必要な場合はMD5やSHA-256のような暗号学的ハッシュ関数が使われますが、考え方の原点は単純チェックサムと同じです。

Q. 他の章とどう繋がりますか?

A. 前の章で扱ったビット演算・バイト単位の処理がそのまま計算の基礎になります。次のCIDRマスクのレッスンでも、32bit整数をビット単位で扱う視点を引き続き使います。

次のレッスン

次は 第6章まとめクイズ に進みましょう。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. チェックサム の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. チェックサム とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. 全バイトを合計する
  2. 合計を 256 で割った余りを返す
  3. 空配列のときは 0 を返す

入出力例

test-cases.txt

checksumSum([])0 checksumSum([0])0 checksumSum([1,2,3])6 checksumSum([100,100,100])44 checksumSum([255,1])0 checksumSum([255,255,255,255])252 checksumSum([10,20,30,40,50])150 checksumSum([128,128])0

ヒント

main.py
main.py
学習モード

メモ

単純チェックサム

⌘S で保存