home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_08_09
/
8n09063a
< prev
next >
Wrap
Text File
|
1990-07-24
|
4KB
|
120 lines
/*
// LISTING 1
*/
/****************************************************************************
//
// crc16.c - generate a ccitt 16 bit cyclic redundancy check (crc)
//
// The code in this module generates the crc for a block of data.
//
****************************************************************************/
/*
// 16 12 5
// The CCITT CRC 16 polynomial is X + X + X + 1.
// In binary, this is the bit pattern 1 0001 0000 0010 0001, and in hex it
// is 0x11021.
// A 17 bit register is simulated by testing the MSB before shifting
// the data, which affords us the luxury of specifiy the polynomial as a
// 16 bit value, 0x1021.
// Due to the way in which we process the CRC, the bits of the polynomial
// are stored in reverse order. This makes the polynomial 0x8408.
*/
#define POLY 0x8408
/*
// note: when the crc is included in the message, the valid crc is:
// 0xF0B8, before the compliment and byte swap,
// 0x0F47, after compliment, before the byte swap,
// 0x470F, after the compliment and the byte swap.
*/
extern crc_ok;
int crc_ok = 0x470F;
/****************************************************************************
//
// crc16() - generate a 16 bit crc
//
//
// PURPOSE
// This routine generates the 16 bit remainder of a block of
// data using the ccitt polynomial generator.
//
// CALLING SEQUENCE
// crc = crc16(data, len);
//
// PARAMETERS
// data <-- address of start of data block
// len <-- length of data block
//
// RETURNED VALUE
// crc16 value. data is calcuated using the 16 bit ccitt polynomial.
//
// NOTES
// The CRC is preset to all 1's to detect errors involving a loss
// of leading zero's.
// The CRC (a 16 bit value) is generated in LSB MSB order.
// Two ways to verify the integrity of a received message
// or block of data:
// 1) Calculate the crc on the data, and compare it to the crc
// calculated previously. The location of the saved crc must be
// known.
// 2) Append the calculated crc to the end of the data. Now calculate
// the crc of the data and its crc. If the new crc equals the
// value in "crc_ok", the data is valid.
//
// PSEUDO CODE:
// initialize crc (-1)
// DO WHILE count NE zero
// DO FOR each bit in the data byte, from LSB to MSB
// IF (LSB of crc) EOR (LSB of data)
// crc := (crc / 2) EOR polynomial
// ELSE
// crc := (crc / 2)
// FI
// OD
// OD
// 1's compliment and swap bytes in crc
// RETURN crc
//
****************************************************************************/
unsigned short crc16(data_p, length)
char *data_p;
unsigned short length;
{
unsigned char i;
unsigned int data;
unsigned int crc;
crc = 0xffff;
if (length == 0)
return (~crc);
do {
for (i = 0, data = (unsigned int)0xff & *data_p++;
i < 8;
i++, data >>= 1) {
if ((crc & 0x0001) ^ (data & 0x0001))
crc = (crc >> 1) ^ POLY;
else
crc >>= 1;
}
} while (--length);
crc = ~crc;
data = crc;
crc = (crc << 8) | (data >> 8 & 0xFF);
return (crc);
}