2006-04-16

CRC-CCITTの計算

モデム等の通信で多く使われているエラーチェックアルゴリズムとしてCRC(巡回冗長検査)があります。このアルゴリズムは、ハード的に比較的簡単なロジックで実現できて、検出能力も比較的高いためよく使われているようです。 CRCの原理については、面倒なのでここでは書きませんw。グーグルってもらえれば、詳しく解説されています。
CRC-CCITTは、CCITTで規格化されたCRCということになります。CCITTは現在ではITUという団体に変わっています。CRCのアルゴリズムを使って何を規格化したかというと、CRCの計算のパラメタとなる、「ビット長」「多項式(polynominal)」「初期値」「ビットを送る方向」ということになります。
CRC-CCITTでは、ビット長は16bit、多項式は1+X^5+X^12+X^16、初期値はFFFF、送りはLSB First(右送り)となります(LSB Firstはプロトコルに依存するかも)。ただし、プロトコルによっては初期値が違う場合もあるようです。
実装コードは、テーブルを使って高速化したもの等が検索するといくつかあるようですが、すなおに簡単なコードで書くと、以下のようになります。

static unsigned short _crcValue=0xFFFF;
static unsigned short _polynomial=0x8408;

unsigned short crcCalc(unsigned char data)
{
 for(unsigned i=0;i<8;i++){
  bool flag=((_crcValue^data)&0x0001)!=0;
  _crcValue>>=1;
  if(flag) _crcValue^=_polynomial;
  data>>=1;
 }
 return _crcValue;
}

1回計算すると_crcValueが変わるかもしれないので、0xFFFFで初期化してから計算するようにします。チェックするデータを順にパラメタにいれて関数を呼び出します。戻り値にCRCの値を返してますが必要なのは最後だけです(0xFFFFになっている)。
実装するときにはもっと賢いコードに書き換えてくださいねw。

1 件のコメント:

Finky さんのコメント...

テーブルを使った高速化については、CRC-CCITTの計算の高速化をご覧ください。Javaのソースを載せました。