CRC-16-CCITT をテーブルを使わないで計算するソースコード
ついでに、テーブルを使わないでCRCを計算する関数も作成しました。どうしても使用するプログラムメモリを削減したい場合向け。
テーブルを使って高速に計算する関数はこちら
テーブルを使って高速に計算する関数はこちら
/*
CRC-16-CCITT を計算する
// wikipediaにある実装例の通り(wikipediaの例は多項式が反転、シフトの向きが右)
// http://ja.wikipedia.org/wiki/%E5%B7%A1%E5%9B%9E%E5%86%97%E9%95%B7%E6%A4%9C%E6%9F%BB
MB8877のデータシートに
X^0+X^5+X^12+X^16 と書いてあったので、フロッピーのCRCは CRC-16-CCITT
2014年9月2日作成
*/
unsigned short crc_1byte(unsigned char in, unsigned short crc)
{
/* 1byteづつCRCを計算する
wikipediaにある実装例を、テーブルを使わないように書き換えただけ。
unsigned short crc;
crc = 0xffff; // 初期値
crc = crc_1byte(0xA1, crc);
crc = crc_1byte(0xA1, crc);
crc = crc_1byte(0xA1, crc);
crc = crc_1byte(0xFE, crc); // A1 A1 A1 FE : ID ADDRESS MARK
crc = crc_1byte(0x02, crc); // C
crc = crc_1byte(0x00, crc); // H
crc = crc_1byte(0x03, crc); // R
crc = crc_1byte(0x02, crc); // N
これで crc に計算結果が入る (0x4165)
*/
#define polynomial 0x1021 // 多項式 CRC-16-CCITT X^16+X^12+X^5+X^0 (1 0001 0000 0010 0001)
// 0x8005 // CRC-16-IBM X^16+X^15+X^2+X^0 (1 1000 0000 0000 0101)
unsigned char bit;
unsigned short a;
a = ((in << 8) ^ crc) & 0xFF00;
for (bit = 8; bit != 0; bit--)
{
if (0 == (a & 0x8000)) a = (a << 1); // 最上位ビットが0ならシフトのみ
else a = polynomial ^ (a << 1); // 最上位ビットが1ならシフトして多項式でXOR
}
crc = a ^ (crc << 8);
return crc;
}
unsigned short crc_block(unsigned char buff[], unsigned short size, unsigned crc)
{
/*
ブロックのCRCを計算する
unsigned short crc;
unsigned char buff[]=
{
0xA1,0xA1,0xA1,0xFE // ID ADDRESS MARK
,0x02 // C
,0x00 // H
,0x03 // R
,0x02 // N
,0x41 // CRC H
,0x65 // CRC L
};
crc = crc_block(buff, 8, 0xFFFF);
これで crc に IDAM から N までの計算結果が入る (0x4165)
crc = crc_block(buff,10, 0xFFFF);
CRCを含めて計算すると、CRCが正しければ計算結果がゼロになる
*/
unsigned short pos;
for(pos=0; pos!=size; pos++)
{
crc = crc_1byte(buff[pos], crc);
}
return crc;
}