I am checking out this function OWI_ComputeCRC16() and when I test the function with OWI_ComputeCRC16(0 >> 8, 0), the return value is 0.
/**
* @brief Compute the CRC16 value of a data set.
* @details This function will compute the CRC16 of inData using seed as inital value for the CRC.
* @note Setting seed to 0 computes the crc16 of the inData.
* @note Constantly passing the return value of this function as the seed argument computes the CRC16 value of a longer string of data.
* @bug N/A
* @warning N/A
* @param unsigned char inData: One byte of data to compute CRC from.
* @param unsigned short seed: The starting value of the CRC.
* @return The CRC16 of inData with seed as initial value.
*/
unsigned short OWI_ComputeCRC16(unsigned char inData, unsigned short seed)
{
unsigned char bitsLeft;
unsigned char temp;
for (bitsLeft = 8; bitsLeft > 0; bitsLeft--)
{
temp = ((seed ^ inData) & 0x01);
if (temp == 0)
{
seed >>= 1;
}
else
{
seed ^= 0x4002;
seed >>= 1;
seed |= 0x8000;
}
inData >>= 1;
}
return seed;
}
This is making some problems in legacy code that I have to solve, where this function is also used with parameters 0, 0 and then SUM of calculated CRC values is used.
Example:
a) I have some data on example position = 0 with key = 0 ... => OWI_ComputeCRC16(0 >> 8, 0) returns 0.
b) I have some data on example position = 0 with key = 0 ... crc = 0. And I have another data record on example position = 1 with key = 1 ... OWI_ComputeCRC16(1 >> 8, 1) returns 49345.
If I do SUM on this returned CRC values, I will not know, if data from position 0 is included or not.
Ok, I think this is logical error and I can solve it.
The question is: is it ok for function, that should calculate and return CRC value, to return value 0 (for any possible given input values)?
p.s.: this is my first question on stackoverflow, so if I did something wrong or not understandable, please let me know. Thanks.
The question is: is it ok for function, that should calculate and return CRC value, to return value 0 (for any possible given input values)?
Not for any, but for some sequences of bytes you will get a zero return value. In fact for a 16-bit CRC, you should expect to get a zero CRC for, on average, one out of every 65536 random sequences you try.
This particular CRC, with no pre or post conditioning, will give a zero CRC for the empty sequence and any sequence of zeros.
By the way, that is an odd implementation with a lot more operations than needed. It should be replaced by this:
unsigned short OWI_ComputeCRC16(unsigned char inData, unsigned short seed)
{
seed ^= inData;
for (int k = 0; k < 8; k++)
seed = seed & 1 ? (seed >> 1) ^ 0xa001 : seed >> 1;
return seed;
}
That also doesn't obfuscate the CRC polynomial, where in this version is the familiar (reflected) 0xa001 or (not reflected) polynomial 0x8005, which is x16+x15+x2+1. Faster still would be a byte-wise or word-wise table-driven version. See crcany.c for examples.