通信プロトコルや組み込み開発の仕様書で頻繁に目にする CRC-16 や CRC-16/CCITT-FALSE について、その概念と仕組み、各種パラメータの意味を備忘録として整理します。
チェックサムとCRC-16の関係性
データ通信やファイル保存において、転送途中でデータが化けていないかを検証する枠組み全般を 誤り検出(Error Detection) と呼びます。送信側がデータ本体から一定の規則で計算した検査値を末尾に付加して送り、受信側でも同じ計算を行って末尾の値と一致するか照合します。
この枠組みの中で使われる検査値は広義に チェックサム と総称されますが、狭義のチェックサムは単に各バイトの値を加算しただけのシンプルな合計値を指します。これに対して CRC(Cyclic Redundancy Check / 巡回冗長検査) は、データをビット列の多項式と見なし、特定の生成多項式で割ったときの 余り を検査値とする高度な計算手法です。
CRCの中で、算出される検査値のサイズが16ビット(2バイト)のものが CRC-16 です。単純な加算チェックサムに比べて連続したビット化け(バースト誤り)の検出能力が極めて高く、産業用通信やマイコン間のシリアル通信で広く採用されています。
CRC-16の挙動を決める5つのパラメータ
「CRC-16」という枠組みだけでは、一意な計算結果を得ることができません。送信側と受信側で計算結果を一致させるためには、アルゴリズムの挙動を決定する 5つのパラメータ を厳密に揃える必要があります。
- 生成多項式 (Polynomial): 割り算の除数となる16ビットの値(例:
0x1021,0x8005) - 初期値 (Init): 計算開始時の内部レジスタに設定する初期値(例:
0x0000,0xFFFF) - 入力反転 (RefIn): 入力バイトのビット順を反転(LSBファースト)して処理するかどうか(
True/False) - 出力反転 (RefOut): 算出された16ビット値のビット順を反転するかどうか(
True/False) - 出力XOR (XorOut): 最終的な算出値に対して最後に排他的論理和(XOR)を行う値(例:
0x0000,0xFFFF)
これらの組み合わせが1つでも異なると、全く同じデータを与えても異なる検査値が出力されてしまいます。
CRC-16/CCITT-FALSEとは何か
CRC-16の仕様の中で、CCITT(現ITU-T)の生成多項式 $x^{16} + x^{12} + x^5 + 1$ (0x1021)を用いつつ、入出力のビット反転を行わない設定のモデルが CRC-16/CCITT-FALSE です。
名称に FALSE と付いているのは、ビット反転パラメータである RefIn および RefOut がともに False に設定されていることに由来します。
| パラメータ名 | 設定値 | 補足 |
| 生成多項式 (Polynomial) | 0x1021 | $x^{16} + x^{12} + x^5 + 1$ |
| 初期値 (Init) | 0xFFFF | 内部レジスタを全ビット1で初期化 |
| 入力反転 (RefIn) | False | MSBファーストで処理 |
| 出力反転 (RefOut) | False | 最終ビット列を反転しない |
| 出力XOR (XorOut) | 0x0000 | 最終値にXORを適用しない |
仕様書で「CRC-16/CCITT-FALSE検証」と指定されている場合は、上記のパラメータに従って送信データの末尾に付加された2バイトのCRC値と、受信側で再計算した値が一致するかどうかを判定することを意味します。