[net.micro] CRC procedure needed

STEVEH@MIT-MC.ARPA (Stephen C. Hill) (10/08/85)

Does anyone have a version of the CRC error checking algorithm in C or Pascal?
I would like to put it in a version of KERMIT that I am writing for the State
of Illinois.

Kushall.henr@XEROX.ARPA (10/08/85)

Steven:

There was a very good article that included this in the June 85 Dr.
Dobbs Journal. The article title is "Christensen Protocols in C" by
Donald Krantz.
The article starts on P66 and there is a special section on CRC on p.68.
This CRC is based on the CCITT polynomial X^16+X^12+X^5+1 (Someone must
know what that means). 

The Source Code in C for the entire XFR communications package can be
downloaded from the TCOG BBS (612) 724-7779 @300/1200 baud

Perhaps this article and code can help you with a KERMIT version of CRC.

Ed Kushall

ron@cylixd.UUCP (Ronald Boyd) (10/11/85)

In article <1975@brl-tgr.ARPA> STEVEH@MIT-MC.ARPA (Stephen C. Hill) writes:
>Does anyone have a version of the CRC error checking algorithm in C or Pascal?
>I would like to put it in a version of KERMIT that I am writing for the State
>of Illinois.

There are numerous versions of CRC algorithms in use. The principal
specifications are CRC-16, CRC-CCITT, and AUTODIN-II CRC
specifications.  DEC includes a CRC assembly language instruction
in the VAX machine code set. The problem with most CRC algorithms
is that they require 8 XOR's and 8 shifts per byte of data encoded.
The following algorithm produces a correct CRC-16 checksum with the
minimum amount of computation and table look ups that we have been
able to develop. If you want CRC-CCITT instead all you have to do
is to change the values of the crctab[] table.

Included in this listing are two functions that compute the CRC
checksum for transmission and check it for reception. The bytes of
the CRC check field are computed separately so that this algorithm
will work on our VAX, MC68000, 6502, and Z8000 based systems. 

XX   #define TXTLEN 128		/* length of data part of a packet */
XX   
XX   
XX   char crctab[] = {
XX   	0x0, 0x0, 0xC0, 0xC1, 0xC1, 0x81, 0x1, 0x40,
XX   	0xC3, 0x1, 0x3, 0xC0, 0x2, 0x80, 0xC2, 0x41,
XX   	0xC6, 0x1, 0x6, 0xC0, 0x7, 0x80, 0xC7, 0x41,
XX   	0x5, 0x0, 0xC5, 0xC1, 0xC4, 0x81, 0x4, 0x40,
XX   	0xCC, 0x1, 0xC, 0xC0, 0xD, 0x80, 0xCD, 0x41,
XX   	0xF, 0x0, 0xCF, 0xC1, 0xCE, 0x81, 0xE, 0x40,
XX   	0xA, 0x0, 0xCA, 0xC1, 0xCB, 0x81, 0xB, 0x40,
XX   	0xC9, 0x1, 0x9, 0xC0, 0x8, 0x80, 0xC8, 0x41,
XX   	0xD8, 0x1, 0x18, 0xC0, 0x19, 0x80, 0xD9, 0x41,
XX   	0x1B, 0x0, 0xDB, 0xC1, 0xDA, 0x81, 0x1A, 0x40,
XX   	0x1E, 0x0, 0xDE, 0xC1, 0xDF, 0x81, 0x1F, 0x40,
XX   	0xDD, 0x1, 0x1D, 0xC0, 0x1C, 0x80, 0xDC, 0x41,
XX   	0x14, 0x0, 0xD4, 0xC1, 0xD5, 0x81, 0x15, 0x40,
XX   	0xD7, 0x1, 0x17, 0xC0, 0x16, 0x80, 0xD6, 0x41,
XX   	0xD2, 0x1, 0x12, 0xC0, 0x13, 0x80, 0xD3, 0x41,
XX   	0x11, 0x0, 0xD1, 0xC1, 0xD0, 0x81, 0x10, 0x40,
XX   	0xF0, 0x1, 0x30, 0xC0, 0x31, 0x80, 0xF1, 0x41,
XX   	0x33, 0x0, 0xF3, 0xC1, 0xF2, 0x81, 0x32, 0x40,
XX   	0x36, 0x0, 0xF6, 0xC1, 0xF7, 0x81, 0x37, 0x40,
XX   	0xF5, 0x1, 0x35, 0xC0, 0x34, 0x80, 0xF4, 0x41,
XX   	0x3C, 0x0, 0xFC, 0xC1, 0xFD, 0x81, 0x3D, 0x40,
XX   	0xFF, 0x1, 0x3F, 0xC0, 0x3E, 0x80, 0xFE, 0x41,
XX   	0xFA, 0x1, 0x3A, 0xC0, 0x3B, 0x80, 0xFB, 0x41,
XX   	0x39, 0x0, 0xF9, 0xC1, 0xF8, 0x81, 0x38, 0x40,
XX   	0x28, 0x0, 0xE8, 0xC1, 0xE9, 0x81, 0x29, 0x40,
XX   	0xEB, 0x1, 0x2B, 0xC0, 0x2A, 0x80, 0xEA, 0x41,
XX   	0xEE, 0x1, 0x2E, 0xC0, 0x2F, 0x80, 0xEF, 0x41,
XX   	0x2D, 0x0, 0xED, 0xC1, 0xEC, 0x81, 0x2C, 0x40,
XX   	0xE4, 0x1, 0x24, 0xC0, 0x25, 0x80, 0xE5, 0x41,
XX   	0x27, 0x0, 0xE7, 0xC1, 0xE6, 0x81, 0x26, 0x40,
XX   	0x22, 0x0, 0xE2, 0xC1, 0xE3, 0x81, 0x23, 0x40,
XX   	0xE1, 0x1, 0x21, 0xC0, 0x20, 0x80, 0xE0, 0x41,
XX   	0xA0, 0x1, 0x60, 0xC0, 0x61, 0x80, 0xA1, 0x41,
XX   	0x63, 0x0, 0xA3, 0xC1, 0xA2, 0x81, 0x62, 0x40,
XX   	0x66, 0x0, 0xA6, 0xC1, 0xA7, 0x81, 0x67, 0x40,
XX   	0xA5, 0x1, 0x65, 0xC0, 0x64, 0x80, 0xA4, 0x41,
XX   	0x6C, 0x0, 0xAC, 0xC1, 0xAD, 0x81, 0x6D, 0x40,
XX   	0xAF, 0x1, 0x6F, 0xC0, 0x6E, 0x80, 0xAE, 0x41,
XX   	0xAA, 0x1, 0x6A, 0xC0, 0x6B, 0x80, 0xAB, 0x41,
XX   	0x69, 0x0, 0xA9, 0xC1, 0xA8, 0x81, 0x68, 0x40,
XX   	0x78, 0x0, 0xB8, 0xC1, 0xB9, 0x81, 0x79, 0x40,
XX   	0xBB, 0x1, 0x7B, 0xC0, 0x7A, 0x80, 0xBA, 0x41,
XX   	0xBE, 0x1, 0x7E, 0xC0, 0x7F, 0x80, 0xBF, 0x41,
XX   	0x7D, 0x0, 0xBD, 0xC1, 0xBC, 0x81, 0x7C, 0x40,
XX   	0xB4, 0x1, 0x74, 0xC0, 0x75, 0x80, 0xB5, 0x41,
XX   	0x77, 0x0, 0xB7, 0xC1, 0xB6, 0x81, 0x76, 0x40,
XX   	0x72, 0x0, 0xB2, 0xC1, 0xB3, 0x81, 0x73, 0x40,
XX   	0xB1, 0x1, 0x71, 0xC0, 0x70, 0x80, 0xB0, 0x41,
XX   	0x50, 0x0, 0x90, 0xC1, 0x91, 0x81, 0x51, 0x40,
XX   	0x93, 0x1, 0x53, 0xC0, 0x52, 0x80, 0x92, 0x41,
XX   	0x96, 0x1, 0x56, 0xC0, 0x57, 0x80, 0x97, 0x41,
XX   	0x55, 0x0, 0x95, 0xC1, 0x94, 0x81, 0x54, 0x40,
XX   	0x9C, 0x1, 0x5C, 0xC0, 0x5D, 0x80, 0x9D, 0x41,
XX   	0x5F, 0x0, 0x9F, 0xC1, 0x9E, 0x81, 0x5E, 0x40,
XX   	0x5A, 0x0, 0x9A, 0xC1, 0x9B, 0x81, 0x5B, 0x40,
XX   	0x99, 0x1, 0x59, 0xC0, 0x58, 0x80, 0x98, 0x41,
XX   	0x88, 0x1, 0x48, 0xC0, 0x49, 0x80, 0x89, 0x41,
XX   	0x4B, 0x0, 0x8B, 0xC1, 0x8A, 0x81, 0x4A, 0x40,
XX   	0x4E, 0x0, 0x8E, 0xC1, 0x8F, 0x81, 0x4F, 0x40,
XX   	0x8D, 0x1, 0x4D, 0xC0, 0x4C, 0x80, 0x8C, 0x41,
XX   	0x44, 0x0, 0x84, 0xC1, 0x85, 0x81, 0x45, 0x40,
XX   	0x87, 0x1, 0x47, 0xC0, 0x46, 0x80, 0x86, 0x41,
XX   	0x82, 0x1, 0x42, 0xC0, 0x43, 0x80, 0x83, 0x41,
XX   	0x41, 0x00, 0x81, 0xC1, 0x80, 0x81, 0x40, 0x40
XX   };
XX   /* crc: given msgp, a pointer to a packet, returns 
XX   the calculated CRC-16 in *bcc1 and *bcc2 */
XX   
XX   crc (msgp, bcc1, bcc2)
XX   char *msgp, *bcc1, *bcc2;
XX   {
XX   	register int i, offset;
XX   
XX   	*bcc1 = *bcc2 = 0;
XX   
XX   	for (i = 0; i < (TXTLEN+2); i++)
XX   	{
XX   		offset = (msgp[i] & 0xFF) ^ (*bcc2 & 0xFF);
XX   		offset <<= 1;
XX   
XX   		*bcc2 = *bcc1 ^ crctab[offset + 1];
XX   		*bcc1 = crctab[offset];
XX   	}
XX   }
XX   rcvcrc (msgp)
XX   char *msgp;
XX   {
XX   	char bcc1, bcc2;
XX   
XX   	crc (msgp, &bcc1, &bcc2);
XX   
XX   	if (*(msgp + (TXTLEN+2)) == bcc2
XX   	    && *(msgp + (TXTLEN+3)) == bcc1)
XX   		return (0);
XX   
XX   	else return (-1);
XX   }
XX   xmtcrc (msgp)
XX   char *msgp;
XX   {
XX   	char bcc1, bcc2;
XX   
XX   	crc (msgp, &bcc1, &bcc2);
XX   
XX   	*(msgp + (TXTLEN+2)) = bcc2;
XX   	*(msgp + (TXTLEN+3)) = bcc1;
XX   }
-- 
--------------------------------------------
Ronald Boyd	(ihnp4!akgub!cylixd!ron)

The above opinions do not represent anyone's but my own.