#include #include #include "crc.h" /* CRC_TABLE[256], the table of cyclic redundancy checksums for all 8-bit messages. CRC_TABLE_COMPUTED, a flag recording whether the table has been computed. */ unsigned long crc_table[256]; int crc_table_computed = 0; /* & is the bitwise AND operator. ^ is the bitwise XOR operator. >> is the bitwise right shift operator. 0xNNN introduces a hexadecimal constant. */ /**********************************************************************/ unsigned long crc ( unsigned char *buf, int len ) /**********************************************************************/ /* Purpose: CRC returns the CRC of the bytes in BUF[0...LEN-1]. Reference: G Randers-Pehrson, et al, PNG (Portable Network Graphics) Specification, Version 1.2, July 1999. Modified: 09 March 2002 */ { return update_crc ( 0xffffffffL, buf, len ) ^ 0xffffffffL; } /**********************************************************************/ void make_crc_table ( void ) /**********************************************************************/ /* Purpose: MAKE_CRC_TABLE makes the table for a fast CRC computation. Reference: G Randers-Pehrson, et al, PNG (Portable Network Graphics) Specification, Version 1.2, July 1999. Modified: 09 March 2002 */ { unsigned long c; int k; int n; for ( n = 0; n < 256; n++ ) { c = ( unsigned long ) n; for ( k = 0; k < 8; k++ ) { if ( c & 1 ) { c = 0xedb88320L ^ ( c >> 1 ); } else { c = c >> 1; } } crc_table[n] = c; } crc_table_computed = 1; } /**********************************************************************/ void print_crc_table ( void ) /**********************************************************************/ /* Purpose: PRINT_CRC_TABLE prints the CRC table. Modified: 25 February 2001 Author: John Burkardt */ { int n; if ( !crc_table_computed ) { make_crc_table ( ); } printf ( "\n" ); printf ( "CRC_TABLE printed in decimal and hex.\n" ); printf ( "\n" ); for ( n = 0; n < 256; n++ ) { printf ( "%d %d %x\n", n, crc_table[n], crc_table[n] ); } return; } /**********************************************************************/ unsigned long update_crc ( unsigned long crc, unsigned char *buf, int len ) /**********************************************************************/ /* Purpose: UPDATE_CRC updates a running CRC. Discussion: The value of CRC should have been initialized to all 1's, and the transmitted value is the 1's complement of the final running CRC. Reference: G Randers-Pehrson, et al, PNG (Portable Network Graphics) Specification, Version 1.2, July 1999. */ { 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; }