/* updcrc(3), crc(1) - calculate crc polynomials * * Calculate, intelligently, the CRC of a dataset incrementally given a * buffer full at a time. * * Usage: * newcrc = updcrc( oldcrc, bufadr, buflen ) * unsigned int oldcrc, buflen; * char *bufadr; * * Compiling with -DTEST creates a program to print the CRC of stdin to stdout. * Compile with -DMAKETAB to print values for crctab to stdout. If you change * the CRC polynomial parameters, be sure to do this and change * crctab's initial value. * * Notes: * Regards the data stream as an integer whose MSB is the MSB of the first * byte recieved. This number is 'divided' (using xor instead of subtraction) * by the crc-polynomial P. * XMODEM does things a little differently, essentially treating the LSB of * the first data byte as the MSB of the integer. Define SWAPPED to make * things behave in this manner. * * Author: Mark G. Mendel, 7/86 * UUCP: ihnp4!umn-cs!hyper!mark, GEnie: mgm */ /* The CRC polynomial. * These 4 values define the crc-polynomial. * If you change them, you must change crctab[]'s initial value to what is * printed by initcrctab() [see 'compile with -DMAKETAB' above]. */ /* Value used by: CITT XMODEM ARC */ #define P 0xA001 /* the poly: 0x1021 0x1021 A001 */ #define INIT_CRC 0L /* init value: -1 0 0 */ #define SWAPPED /* bit order: undef defined defined */ #define W 16 /* bits in CRC:16 16 16 */ /* data type that holds a W-bit unsigned integer */ #if W <= 16 # define WTYPE unsigned short #else # define WTYPE unsigned long #endif /* the number of bits per char: don't change it. */ #define B 8 static WTYPE crctab[1<>(W-B)) ^ *cp++]; #else crc = (crc>>B) ^ crctab[(crc & ((1< main() { initcrctab(); } initcrctab() { register int b, i; WTYPE v; for( b = 0; b <= (1<= 0; ) v = v & ((WTYPE)1<<(W-1)) ? (v<<1)^P : v<<1; #else for( v = b, i = B; --i >= 0; ) v = v & 1 ? (v>>1)^P : v>>1; #endif crctab[b] = v; printf( "0x%lx,", v & ((1L< #include #define MAXBUF 4096 main( ac, av ) int ac; char **av; { int fd; int nr; int i; char buf[MAXBUF]; WTYPE crc, crc2; fd = 0; if( ac > 1 ) if( (fd = open( av[1], O_RDONLY )) < 0 ) { perror( av[1] ); exit( -1 ); } crc = crc2 = INIT_CRC; while( (nr = read( fd, buf, MAXBUF )) > 0 ) { crc = updcrc( crc, buf, nr ); } if( nr != 0 ) perror( "reading" ); else { printf( "%lx\n", crc ); } #ifdef MAGICCHECK /* tack one's complement of crc onto data stream, and continue crc calculation. Should get a constant (magic number) dependent only on P, not the data. */ crc2 = crc ^ -1L; for( nr = W-B; nr >= 0; nr -= B ) { buf[0] = (crc2 >> nr); crc = updcrc(crc, buf, 1); } /* crc should now equal magic */ buf[0] = buf[1] = buf[2] = buf[3] = 0; printf( "magic test: %lx =?= %lx\n", crc, updcrc(-1, buf, W/B)); #endif MAGICCHECK } #endif ****************************************************************************