Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!linus!philabs!cmcl2!seismo!think!caip!meccts!dicome!mmm!umn-cs!hyper!mark From: mark@hyper.UUCP (Mark Mendel) Newsgroups: net.sources Subject: fast crc routine Message-ID: <68@hyper.UUCP> Date: Wed, 9-Jul-86 19:31:34 EDT Article-I.D.: hyper.68 Posted: Wed Jul 9 19:31:34 1986 Date-Received: Fri, 11-Jul-86 21:54:06 EDT Distribution: net Organization: Network Systems Corp., Mpls., Mn. Lines: 157 "...doesn't support CRC transfers, but I've not had any trouble with checksums" -- an lucky fool "Death to Checksums!" -- me For some reason, many of the binaries for Macintoshes that we receive here in the mn area from Usenet have crc errors when we try to unpack them. Upon inspecting one of these files (it was a font, so easy to check visually!), I noticed DOUBLE BIT ERRORS. These puppies occur when somebody transfers over a noisy line using only a checksum protocol. In fact, if you EVER (even rarely), see errors while transmitting, eventually you will get a double bit error, which will not be detected by a checksum. To encourage the use of CRC's, I am posting a FAST crc calculator. It is set up to calculate the CRC used by the popular XMODEM protocol. This routine is at least 5 times as fast as the one used by rb, a recectly distruted XMODEM program for unix. This is NOT a shar file. ------------- cut here -------- /* updcrc - calculate crc polynomials * * Calculate, intelligently, the CRC of a dataset incrementally given a * buffer full at a time. * Initialize crc to 0 for XMODEM, -1 for CCITT. * * Usage: * newcrc = updcrc( oldcrc, bufadr, buflen ) * unsigned int oldcrc, buflen; * char *bufadr; * * Compile with -DTEST to generate program that prints CRC of stdin to stdout. * Compile with -DMAKETAB to print values for crctab to stdout */ /* the CRC polynomial. This is used by XMODEM (almost CCITT). * If you change P, you must change crctab[]'s initial value to what is * printed by initcrctab() */ #define P 0x1021 /* number of bits in CRC: don't change it. */ #define W 16 /* this the number of bits per char: don't change it. */ #define B 8 static unsigned short crctab[1<>(W-B)) ^ *cp++]; } return( crc ); } #ifdef MAKETAB main() { initcrctab(); } initcrctab() { register b, v, i; for( b = 0; b <= (1<= 0; ) v = v&0x8000 ? (v<<1)^P : v<<1; crctab[b] = v; printf( "0x%04x,", v & 0xFFFF ); if( (b&7) == 7 ) printf("\n" ); else printf(" "); } } #endif #ifdef TEST #include #include #define MAXBUF 4096 main( ac, av ) int ac; char **av; { int fd = 0; int nr; char buf[MAXBUF]; unsigned short crc; if( ac > 1 ) if( (fd = open( av[1], O_RDONLY )) < 0 ) { perror( av[1] ); exit( -1 ); } crc = 0; while( (nr = read( fd, buf, MAXBUF )) > 0 ) crc = updcrc( crc, buf, nr ); printf( "%04x\n", crc ); if( nr != 0 ) perror( "reading" ); } #endif -- ------------------------------------------- Mark G. Mendel, Network Systems Corporation ihnp4!umn-cs!hyper!mark