より理論的なエラー検出コードとして、Cyclic Redundancy Check(CRC)というコードがある。
少し形式張るが、nビットのデータan-1、an-2、…、a0を0か1の値をとる係数とする
an-1Xn-1+an-2Xn-2+…+a2X2+a1X1+a0
という多項式と考え、これをある多項式で割り、その余りをチェックビットとする。この割り算をする多項式は整数でいうと素数のような因数分解できない多項式で、16ビットのチェックビットの場合は、
X16+X12+X5+1
がX.25やBluetoothなどで伝送エラーを検出するために用いられている。また、IEEE802.3では
X32+X25+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X+1
という多項式を使い、32ビットのチェックビットを作っている。
このように作られたCRCでは1ビットエラーが検出できるだけでなく、n-1ビット以下の長さの範囲内であれば、その中に複数のエラービットがあっても検出できることが保証されている。通信の場合は雑音で連続した複数のビットが誤るという場合が多く、このように連続した複数ビットのエラーが検出できるというのは大きなメリットである。
多項式での割り算は、図2.11に示すようにチェックビットの長さのシフトレジスタを使い、係数が1の項(前述の16ビットの例では12と5)の所にXORを入れて引き算(係数が2進数の場合は足し算と同じ)を行うことで実現できる。図2.11の右側から順にデータビットを入れ、すべてのデータビットがシフトインされた時点でのシフトレジスタの内容がチェックビットとなっているので、これをシフトアウトしてデータに付加してやれば良い。
CRCは、このようにシフトレジスタを用いると比較的簡単な回路で実現できる。そして、入力データビットを順次シフトインしていくので、通信のように順次データを送るという場合は良いのであるが、コンピュータのバスのように並列にデータを伝送する場合にはチェックビットの生成に時間が掛ってしまうという問題がある。このため、CRCはブロックでデータを順次伝送するEthernetなどの通信や、ディスクとのデータのブロック伝送などには広く使われているが、並列伝送を行うプロセサ内部のデータバスなどでは、CRCは用いられない。