Reputation: 561
For functional safety reasons I need to store a crc-16 or similar for protection of data. Data length would be up to 80 bytes. I need to use one value of the 16bit value for indication, that the data was modified intentionally and crc is not calculated yet.
As far as I understand, every value of a 16bit value could be the result of CRC-16. There is no unused value which could indicate "uninitialised".
What is the best solution?
take "0" as the uninitialised value and store "1" if the calculation delivers "0"
use a smaller CRC, e.g. CRC-15
is there a better solution?
I use C and C++ but this should not play a big role.
Update, taking into account the suggestion of rcgldr to use CRC-15: I will calculate CRC-15 value (which is 0..32767) or the value 65432 which should indicate that the data should be checked and the CRC calculated. I want not use only 1 bit or 0x0000 or 0xFFFF for invalidating the crc, as these bit patterns could occur more likely than an odd number, outside the valid range of CRC-15, like 65432.
Taking into account the suggestion of Adler: I calculate CRC-16 and if the value is 65432, write e.g. 0xFFFF instead. 65432 is thus reserved for indicating the modification.
I have the feeling that CRC-15 looks more clean, but Adler is right that I loose information. On the other hand my data (calibration data) are stored in memory and bit errors are not so likely like it would be with data transfer via serial interface (this will be protected seperately). The chance that an error is not detected is about 1:32767.
Upvotes: 0
Views: 154
Reputation: 28828
Without knowing why or how often a CRC is not initialized (calculated), the expected error rate and how non-initialized CRC is handled, I'm not sure what to recommend.
take "0" as the uninitialised value and store "1" if the calculation delivers "0
Both 0 and 1 are possible valid and invalid (indicating error) CRC 16 values, but as Mark Adler answered, it only slightly weakens the CRC, since a calculated CRC of 0 or 1 are both mapped to 1. When the data is received, and the CRC recalculated on just the data, then if the message CRC == 1, the code would accept recalculated CRC of 0 or 1 as indicating no errors.
use a smaller CRC, e.g. CRC-15
Use a 15 bit CRC and a flag bit to indicate if the 15 bit CRC is calculated or not. As Mark Adler answered, it's weaker than having 0 and 1 mapped to 1, but if the error rate for 82 bytes is very low, it may not matter from a practical standpoint.
Upvotes: 0
Reputation: 112239
Your first option. You can preserve most of the power of a 16-bit CRC by mapping a CRC value of 0 to 1. Then the value 1 appears twice as often as the other non-zero values, and 0 never appears. This very slightly weakens the power of the CRC to detect errors, and you have now freed up the zero value to indicate that the CRC has not been calculated.
Taking an entire bit for that indication weakens the power of the CRC, indicated by the probability of a false positive, by a factor of two.
Upvotes: 1