The following C functions create and use a CRC lookup table. The output of this program is text for a statically initialized array that you may include in your program. The test cases verify that the lookup function works.
\#include \<stdio.h\>
static unsigned table[256];
void PrintTable(void);
void BuildXMODEM(void);
unsigned XMODEMcrc(unsigned char byt, unsigned crc);
unsigned crc_buf(unsigned char *buf, unsigned length, unsigned crc);
void main(void)
{
unsigned crc;
printf("/* XMODEM crc table */\n");
BuildXMODEM();
/* Do this only once.*/
/* No need to do this at all if the array is statically initialized. */
PrintTable();
crc = 0;/* It is important to initialize the CRC! */
crc = XMODEMcrc('M', crc);
if (crc != 0x9969)
printf("Test case 1 failed. crc = %04X.\n", crc);
crc = 0;
crc = XMODEMcrc('T', crc);
if (crc != 0x1A71)
printf("Test case 2 failed. crc = %04X.\n", crc);
crc = 0;
crc = XMODEMcrc('T', crc);
crc = XMODEMcrc('H', crc);
crc = XMODEMcrc('E', crc);
if (crc != 0x1E0A)
printf("Test case 3 failed. crc = %04X.\n", crc);
crc = 0;
crc = crc_buf("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ", 36, crc);
crc = crc_buf("abcdefghijklmnopqrstuvwxyz!@#$%^&*()", 36, crc);
if (crc != 0xA18A)
printf("Test case 4 failed. crc = %04X.\\n", crc);
}
void PrintTable(void)
/* Print the table for including in a C program. */
{
int i;
printf("unsigned table[256] = \n{\n");
for (i=0; i < 256; I++)
{
if ((i % 8) == 0)
putchar('\t');
printf("0x%04X, ", table[i]);
if (((i+1) % 8) == 0)
putchar('\n');
}
printf("};\n\n");
}
void BuildXMODEM(void)
/* Initialize the table at run-time */
{
int i;
unsigned char z;
for (i=0; i < 256; I++)
{
z = i ^ (i >> 4);
table[i] = z ^ ((unsigned)z << 5) ^ ((unsigned)z << 12);
}
}
unsigned XMODEMcrc(unsigned char byt, unsigned crc)
/* Update the CRC with a new byte */
{
crc = (crc << 8) ^ table[byt ^ (crc >> 8)];
return crc;
}
unsigned crc_buf(unsigned char *buf, unsigned length, unsigned crc)
/* Calculate the crc of a buffer full of characters */
{
while (length--)
{
crc = XMODEMcrc(*buf, crc);
buf++;
}
return crc;
}