I did test a crc-16/ibm implementation i found on the net. when I test it with hex byte array it works fine but if I include some 0x00 values, then it doesn't give the proper result. here is its code
unsigned short ComputeCRC16(const unsigned char* buf, unsigned int len) {
unsigned short crc = 0;
for (unsigned int j = 0; j < len; j )
{
unsigned char b = buf[j];
for (unsigned char i = 0; i < 8; i )
{
crc = ((b ^ (unsigned char)crc) & 1) ? ((crc >> 1) ^ 0xA001) : (crc >> 1);
b >>= 1;
}
}
return crc;
}
I tested it with this code:
int main() {
//fe b5 5f f7
unsigned char buf1[4096] = { 0xfe, 0xb5, 0x5f, 0xf7 };
//fe b5 00 5f f7 00
unsigned char buf2[4096] = { 0xfe, 0xb5, 0x00, 0x5f, 0xf7, 0x00 };
int a = strlen(buf1);
unsigned short res = ComputeCRC16(buf1, a);
printf("res = x\n", res); //res : 7858, the result is correct
int b = strlen(buf2);
unsigned short res = ComputeCRC16(buf2, b);
printf("res = x\n", res); //res : d781, the result is not correct
return 0; //the correct result : 26EE
}
to verify the result I use this website: https://www.lammertbies.nl/comm/info/crc-calculation
CodePudding user response:
Your CRC routine gives correct results. It is your test that's wrong. strlen(p)
returns how many bytes there are before the first zero byte at p
. For buf2
, that's four, not five as you intended. For buf1
it's not even defined, since there can be anything in memory after that array. You might be getting four, if the compiler happened to put zeros after the array.
For testing, you should simply provide len
manually. (buf1, 4)
, (buf2, 5)
.
By the way, that code could be more efficient. It doesn't have to test with b
every time. Just exclusive-oring with b
to start has the same effect:
crc ^= buf[j];
for (unsigned char i = 0; i < 8; i )
crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;