Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site cylixd.UUCP Path: utzoo!linus!decvax!harpo!whuxlm!akgua!akgub!cylixd!ron From: ron@cylixd.UUCP (Ronald Boyd) Newsgroups: net.micro Subject: Re: CRC procedure needed Message-ID: <355@cylixd.UUCP> Date: Fri, 11-Oct-85 09:12:35 EDT Article-I.D.: cylixd.355 Posted: Fri Oct 11 09:12:35 1985 Date-Received: Sat, 12-Oct-85 07:22:57 EDT References: <1975@brl-tgr.ARPA> Reply-To: ron@cylixd.UUCP (Ronald Boyd) Organization: RCA Cylix Communications , Memphis, TN Lines: 136 Summary: 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.