I'm trying to interface with a 3rd party system and they have provided a code sample to calculate a CRC value when sending text data.
The C code the vendor provided looks like this:
#define CRCRES 0xf0b8 /* residue for good verify */
#define DEBUG
unsigned crctbl[] = {0x0000, 0x1081, 0x2102, 0x3183,
0x4204, 0x5285, 0x6306, 0x7387,
0x8408, 0x9489, 0xa50a, 0xb58b,
0xc60c, 0xd68d, 0xe70e, 0xf78f};
/*
* This uses a 32 byte table to lookup the crc 4 bits at a time.
* The CRC CCITT is used.
*/
unsigned short calc_crc(unsigned char *ptr, unsigned length)
{
unsigned short crc;
unsigned short i;
unsigned char pos,ch;
crc = 0xffff; /* precondition crc */
for (i = 0; i < length; i++,ptr++) {
ch = *ptr;
pos = (crc ^ ch) & 15;
crc = ((crc >> 4) & 0x0fff) ^ crctbl[pos];
ch >>= 4;
pos = (crc^ch) & 15;
crc = ((crc >> 4) & 0xffff) ^ crctbl[pos];
}
crc = ~crc; /* post condition */
crc = (crc << 8) | (crc >> 8); /* bytewise reverse */
return crc;
}
/*
* tests the block of code containing the crc to verify it's
* content. This compares to the reversed and inverted
* residue.
*/
int test_crc(unsigned char *ptr, unsigned length)
{
unsigned short crc;
unsigned char arr [] = {'X','Y','Z'};
crc = calc_crc(arr,3);
printf("Calced crc of test to be %04x, (should be 470f)\n", crc);
return (crc == 0x470f);
}
I've copied this code and put in a sample C program. The test_crc method is not calculating the CRC to be 470f (its calculating it as DD7A).
I'm hoping someone can either verify that this code doesn't work as the vendor is saying it should or help me get test_crc to return the correct value.
Thanks for the help.
Problem solved. The specs from the vendor were incorrect. The correct checksum for XYZ is DD7A. The documentation was incorrect.
Add that to the fact that on the page before when they explain what data to pass to the calc_crc method to get the crc for an actual message is also incorrect it made it a tricky project.
Thanks for the help.
The calculation, as it goes, don't show any error that comes to my mind. Just review again the algorithm. In particular, looking for possible problems, note that constants being anded in different parts of the algorithm are 0x0fff
and 0xffff
. Maybe should it be 0x0fff
and 0xfff0
to be more symmetric... Sometimes we think the real problem may come from another place, and forget to double check the obvious things... :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With