[comp.sources.wanted] Cyclic Redundancy Check Routine Wanted

lee@srs.UUCP (Lee Hasiuk) (01/14/88)

Does anybody out there have an efficient C routine which can be used to 
calculate a CRC for a block of data?  CRC16 would be nice, but any CRC 
calculator would suffice.

Thanks!

Lee Hasiuk
{rutgers,ames,allegra}!rochester!srs!lee

robert@hslrswi.UUCP (J. Robert Ward) (01/14/88)

In article <532@srs.UUCP> lee@srs.UUCP (Lee Hasiuk) writes:
>Does anybody out there have an efficient C routine which can be used to 
>calculate a CRC for a block of data?  CRC16 would be nice, but any CRC 
>calculator would suffice.
>
>Thanks!
>
>Lee Hasiuk
>{rutgers,ames,allegra}!rochester!srs!lee

I used the following routine to calculate a 16 bit CRC. As stated,
this routine is a C transcription of an old assembler routine that
was coded for maximum efficiency. The way is works is really pretty
nasty but it should be fast.

Cheers,
	- R.

/******************* C U T  H E R E *******************************/
unsigned	crc ( chp, end )

register char			*chp ;		/* Starting byte */
char				*end ;		/* Ending byte */

{
	register unsigned	c ;
	unsigned		crcadd() ;

	c = 0 ;
	do
		c = crcadd( (unsigned)*chp++, c ) ;
	while ( chp < end ) ;
	return ( c ) ;
}

/*
** CRCADD - Adds the value specified by `ch' into the CRC value specified
** by `c'. This is a cyclic redundancy check with polynomial
** `x**16 + x**12 + x**5 + 1'. Many thanks to Albert Labadi who designed
** and wrote an assembler version of this algorithm (hence the variables
** `r0' and `r2' below). The CRC is computed as a 16 bit checksum.
*/
unsigned	crcadd ( ch, c )

unsigned			ch ;
register unsigned		c ;

{
	register unsigned	r0 ;
	register unsigned	r2 ;

	r0 = (ch << 8) | (c >> 8) ;
	c &= 0x00ff ;
	r2 = c << 4 ;
	r2 &= 0x00f0 ;
	r2 ^= c ;
	r2 <<= 8 ;
	r0 ^= r2 ;
	r2 >>= 5 ;
	r0 ^= r2 ;
	r2 >>= 7 ;
# ifdef M68000
	return ( (unsigned short)(r0 ^ r2) ) ;
# else
	return ( r0 ^ r2 ) ;
# endif
}

/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    J. Robert Ward,						   ___________
    Hasler AG, Belpstrasse 23, CH-3000 Berne 14, Switzerland	   |    _    |
								   |  _| |_  |
Tel.:	    +41 31 633922					   | |_   _| |
X.400:	    robert@hslrswi.hasler				   |   |_|   |
Bitnet:	    robert%hslrswi.UUCP@cernvax.BITNET	   		   |_________|
Uucp:	    ... {uunet,ukc,mcvax ... }!cernvax!hslrswi!robert
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/