/* CRC xx : CRC test program used CRC_TABLE[256] Ex1) CRC-16 : 1 + X^2 + X^15 + X^16 1010 0000 0000 0001 = 0xA001 seri-para form input data : serial 1'st bit -> 8 bit data LSB output CRC : serial 1'st bit -> 16 bit data LSB shift register logic : initialize all 1....1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 --> shift _ _ XOR _ _ _ _ _ _ _ _ _ _ _ _ _ XOR _ __| |_| |___| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |___| |_ --> output CRC | |_| |_| + |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| + |_| | | | | | |__________|_____________________________________________________|_____+ __<-- input data XOR Ex2) CRC-32 : 1 + X + X^2 + X^4 + X^5 + X^7 + X^8 + X^10 + X^11 + X^12 + X^16 + X^22 + X^23 + X^26 + X^32 1110 1101 1011 1000 1000 0011 0010 0000 = 0xEDB88320 */ #include #include #include void make_crc_table(void); unsigned long update_crc(unsigned long crc, unsigned char *buf, int len); unsigned long crc(unsigned char *buf, int len); /* Table of CRCs of all 8-bit messages. */ unsigned long crc_table[256]; /* Flag: has the table been computed? Initially false. */ int crc_table_computed = 0; /* Make the table for a fast CRC. */ void make_crc_table(void) { unsigned long c; int n, k; for (n = 0; n < 256; n++) { c = (unsigned long) n; for (k = 0; k < 8; k++) { if (c & 1) //c = 0xa001L ^ (c >> 1); c = 0xedb88320L ^ (c >> 1); else c = c >> 1; } crc_table[n] = c; } crc_table_computed = 1; } /* Update a running CRC with the bytes buf[0..len-1]--the CRC should be initialized to all 1's, and the transmitted value is the 1's complement of the final running CRC (see the crc() routine below)). */ unsigned long update_crc(unsigned long crc, unsigned char *buf, int len) { unsigned long c = crc; int n; if (!crc_table_computed) make_crc_table(); for (n = 0; n < len; n++) { c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); } return c; } /* Return the CRC of the bytes buf[0..len-1]. */ unsigned long crc(unsigned char *buf, int len) { //return update_crc(0xffffL, buf, len); return update_crc(0xffffffffL, buf, len); } void main( void ) { int i, j; unsigned long result; unsigned char buf[10]; /* 実行するたびに違う値が得られるように、現在の時刻値を使って * 乱数ジェネレータを初期化します。 */ srand( (unsigned)time( NULL ) ); /* 10 個の値を表示します。 */ for( i = 0; i < 10;i++ ) { buf[i] = rand()%256; printf( " %6d\n", buf[i] ); } /* by crc_table */ result = crc(buf,10); //printf( "\n CRC-16 = 0x%x by CRC_TABLE \n", result); printf( "\n CRC-32 = 0x%x by CRC_TABLE \n", result); /* by shift register logic */ //result = 0xffff; result = 0xffffffff; for( i = 0; i < 10;i++) { for( j = 0; j < 8;j++) { if((result^buf[i])&1) //result = 0xa001L ^ (result >> 1); result = 0xedb88320L ^ (result >> 1); else result = result >> 1; buf[i] = buf[i] >> 1; } } //printf( "\n CRC-16 = 0x%x by Shift Reg. Logic \n", result); printf( "\n CRC-32 = 0x%x by Shift Reg. Logic \n", result); }