CRC計算ツール

通信やファイル、メモリのデータが壊れていないかを確かめるCRC(巡回冗長検査)の値を計算します。よく使う種類はプリセットから選べ、幅・生成多項式・初期値・ビット反転・最後のXORを指定して、仕様書どおりのCRCかどうかを確かめられます。短いデータでは、CRCの正体である多項式の割り算を1段ずつ表示します。

入力

結果

CRC(16進数)
–
CRC(2進数)
–
CRC(10進数)
–
データの長さ
–
確認値("123456789" のCRC)
–
生成多項式(式)
–

多項式の割り算の途中

計算は1ビットずつ行う素直な方法で、表を使う高速な実装と同じ結果になります。確認値は、パラメータが正しいかを仕様書やライブラリの値と比べるのに使えます。

CRCとは: 多項式の割り算の余り

CRC(巡回冗長検査)は、データのビット列を2を法とする多項式の係数とみなし、生成多項式で割った余りを検査用の値として付ける方法です。2を法とする計算では足し算も引き算もXORになるので、割り算は「先頭が1なら生成多項式をXORして1桁ずらす」の繰り返しになります。幅wビットのCRCでは、データの後ろにw個の0を付けてから割り、余りのwビットをデータの後ろに付けて送ります。受け取った側が同じ計算をして余りが一致すれば、途中で壊れていないと判断します。種類をCRC-8にしてデータを「A」にすると、0100 0001の後ろに0を8個付けて x⁸ + x² + x + 1(0x07)で割る様子を確かめられます。

初期値・ビット反転・最後のXOR

実際の規格のCRCは、割り算の余りそのものではなく、いくつかの約束を足して定義されています。初期値はレジスタを0以外の値(多くはすべて1)から始めるもので、先頭に0が続くデータでも値が変わるようにします。入力のビット反転は、各バイトを最下位ビットから送るシリアル通信(UARTやイーサネット)に合わせるためのもので、出力のビット反転と組で使われます。最後のXORは、結果をすべて1で反転するなどの操作です。たとえばCRC-32は、多項式0x04C11DB7、初期値0xFFFFFFFF、入出力とも反転、最後に0xFFFFFFFFをXORと定義され、"123456789"のCRCは0xCBF43926です。同じ多項式0x1021でも、CRC-16/CCITT-FALSE(0x29B1)、XMODEM(0x31C3)、KERMIT(0x2189)のように約束が違うと結果が変わります。

CRCが見つけられる誤り

生成多項式をうまく選ぶと、CRCは多くの種類の誤りを確実に見つけられます。幅wビットのCRCは、長さw以下の連続した誤り(バースト誤り)をすべて検出できます。生成多項式が x + 1 を因数に持てば奇数個のビット誤りをすべて検出でき、適切な多項式なら、ある長さまでのデータで2ビットの誤りもすべて検出できます。それ以外のでたらめな誤りを見逃す確率は、おおよそ 2⁻ʷ で、CRC-32なら約43億分の1です。一方、CRCは誤りを見つけるだけで、どのビットが誤ったかは分からないので、訂正が必要なメモリなどではハミング符号などのECCを使います。

どこで使われているか

CRCは、イーサネットのフレームの最後に付くFCS(CRC-32)、PCI Expressのパケット、USB、CAN、SDカードやストレージのコマンド、ZIPやPNGなどのファイル形式、Modbusのような産業用の通信(CRC-16/MODBUS)など、あちこちで使われています。ハードウェアでは、シフトレジスタとXORゲートだけでつくれる線形帰還シフトレジスタ(LFSR)として1ビットずつ計算でき、ソフトウェアでは256個の値の表を使ってバイト単位で高速に計算します。iSCSIやストレージで使われるCRC-32C(Castagnoli)は、x86やArmの命令で計算できるCPUもあります。

仕様どおりのCRCになっているか確かめる

CRCの値が合わないときは、パラメータのどれかが仕様と違っていることがほとんどです。まず、仕様書やライブラリにある"123456789"の確認値と、このツールの確認値が一致するかを見てください。一致しなければ、初期値、ビット反転、最後のXOR、生成多項式の書き方(最上位のx^wを省いた形か、ビット反転した形か)を順に疑います。次に、CRCを計算する範囲(ヘッダを含むか)と、送るときのバイトの順番(CRC-16の上位バイトと下位バイトのどちらを先に送るか)を確かめます。このツールで16進数のバイト列を入れて、実際に通信で流れたデータのCRCと比べると切り分けやすくなります。

インターフェースの問題を解く

PCI Expressのデータリンク層が、伝送中のビットの誤りに対して行うこととして正しいものはどれか。

  1. A誤りがあっても何もせず、ソフトウェアが気づくまでそのまま使う
  2. B誤りが見つかったら、その機器の電源を切る
  3. CパケットにCRCを付けて誤りを検出し、誤りがあれば受け取れなかったことを知らせて送り直させる
答えと解説を見る

正解:C. パケットにCRCを付けて誤りを検出し、誤りがあれば受け取れなかったことを知らせて送り直させる

データリンク層は、各パケットに通し番号とCRC(巡回冗長検査)の符号を付けて送ります。受け側はCRCを確かめ、正しければACK、誤りがあればNAKを返し、送り側は確認が取れるまでパケットを手元に残しておいて、NAKを受けたら送り直します。この仕組みのおかげで、物理層でまれにビットの誤りが起きても、上の層やソフトウェアには正しいデータが届きます。

シフトレジスタの一部の出力のXORを入力に戻す線形帰還シフトレジスタ(LFSR)の代表的な用途はどれか。

  1. A疑似乱数パターンの生成や、テストでのパターン生成・CRC計算
  2. B正確な時刻を計る
  3. Cアナログ信号を増幅する
答えと解説を見る

正解:A. 疑似乱数パターンの生成や、テストでのパターン生成・CRC計算

LFSRは適切なタップを選ぶと、nビットで全0を除く 2ⁿ − 1 通りの状態を巡回する、一見ランダムな系列(M系列)を生成します。XORとフリップフロップだけで作れるため、内蔵テスト(BIST)のパターン生成と結果の圧縮、イーサネットなどのCRC計算、信号を平均化して電磁ノイズを減らすスクランブラに使われます。系列は予測可能なので、暗号用の乱数には使えません。

よくある質問

CRC-16にはなぜ種類がたくさんあるのですか?

CRC-16という名前は幅が16ビットであることしか表しておらず、生成多項式、初期値、ビット反転、最後のXORの組み合わせは規格ごとに違うからです。たとえばModbusはCRC-16/MODBUS(0x8005、初期値0xFFFF、反転あり)、XMODEMは0x1021で初期値0、反転なしです。使う規格がどのパラメータかを確かめて、プリセットかカスタムで合わせてください。

"123456789" の確認値とは何ですか?

ASCIIの"123456789"(9バイト)のCRCで、CRCの種類ごとに決まった値です。パラメータの組み合わせが正しいかを確かめる目印として、CRCのカタログやライブラリの説明によく載っています。CRC-32なら0xCBF43926、CRC-16/MODBUSなら0x4B37です。

CRCとチェックサムの違いは何ですか?

チェックサムはバイトを足し合わせるなどの単純な計算で、データの順番の入れ替えや、打ち消し合う誤りを見逃しやすい方法です。CRCは多項式の割り算に基づくので、ビットの位置まで区別し、バースト誤りなどを確実に見つけられます。そのため、通信や記録の誤り検出には主にCRCが使われます。

CRCで誤りを訂正できますか?

一般にはできません。CRCは誤りがあるかどうかを見つける符号で、どのビットが誤ったかは分からないため、見つけたら再送などで回復します。メモリのように再送できない場面では、ハミング符号やBCH符号、LDPC符号などの訂正できる符号(ECC)を使います。

16進数のバイト列はどう入力しますか?

「31 32 33」「313233」「0x31,0x32,0x33」のように、2桁ずつのバイトを並べて入力します。空白、コンマ、コロン、ハイフンと「0x」は無視します。文字列を選ぶと、入力した文字をUTF-8のバイト列にしてから計算します。

関連する用語

CRC(巡回冗長検査) ECC(誤り訂正符号) ビット誤り率 8b/10b符号化

関連する計算ツール

半導体・電子回路・情報の計算ツール →