What happens if CRC divisor is corrupted during transmission? - crc

We use CRC for error detection in Data during transmission.In CRC we divide Data by Divisor to check whether the data has error or not. But what happens in case the Divisor gets corrupted during transmission? how do we make sure that it doesn't happen.

The CRC polynomial is not transmitted. It is agreed to ahead of time when the protocol is defined, so both the transmit and the receive side already know the polynomial.

Related

Reed solomon error correction and false positives

I have a Reed-Solomon encoder/decoder. After manipulating data and evaluating the results, I have experienced the following 3 cases:
The decoder decodes the message correctly and does not throw an error
The decoder decodes the message to a wrong result, without complaining - effectively producing a false positive. The chance should be very low, but can happen, even if the number of manipulated data is far below the error correction ability (even after changing a single bit...)
The decoder fails (throws an error), if more data is manipulated, than what is allowed by its error correction ability.
Are all 3 cases valid for a proper Reed-Solomon decoder? I am especially unsure about case 2, where the decoder would produce a wrong result (without throwing an error), even if there are much fewer errors than what is allowed by its correction abilities...?
mis-correction below error correction ability
This would indicate a bug in the code. A RS decoder should never fail if there are less than ⌊(n-k)/2⌋ errors.
correction detects when there more errors then error correction ability
Even if there are more than ⌊(n-k)/2⌋ errors, there is a good chance that a RS decoder will still detect an uncorrectable error, as most error patterns would not result in a received codeword that is within ⌊(n-k)/2⌋ or fewer error symbols of a valid codeword, since a working RS decoder should only produce a valid codeword or indicate an uncorrectable error. Miscorrection of more than ⌊(n-k)/2⌋ errors involves the decoder creating an additional ⌊(n-k)/2⌋ or fewer error symbols, resulting in a valid codeword, but one that differs from the original by n-k+1 or more symbols.
Detecting an uncorrectable error can be done by regenerating syndromes for the corrected codeword, but it's usually caught sooner when solving the error locator polynomial (normally done by looping through all possible locator values), when it produces fewer locators than it should due to duplicate or missing roots.
I wrote some interactive RS demo programs in C, for both 4 bit and 8 bit fields, that include the 3 most common decoders (PGZ (matrix), BM (discrepancy), SY (extended Euclid)). Note the SY - extended Euclid decoders in my examples emulate a hardware register oriented solution, two registers, always shift left, each register holds two polynomials where the split shifts left along with the register. The right half of each register is reversed (least significant coefficient first). The wiki article example may be easier to follow.
http://rcgldr.net/misc/eccdemo4.zip
http://rcgldr.net/misc/eccdemo8.zip

Is there a simple way to make a CRC checksum match a given value?

I'm working on a program running on a micro controller and need to implement a self-test for the program code integrity.
For this, I let the code calculate a CRC16 checksum over the whole flash memory (program space) and transmit this value to another system via some network. The other system then has to compare the checksum against a pre-calculated value.
However, with each update, the CRC value changes. So the whole process could be simplified, if the program code can be prepared beforehand, such that the CRC16 checksum always matches a predefined value like 0 or better something like 0x1234.
Is there an easy way to achieve this?
Another way to put this: can I easily calculate a byte sequence, that I would have to add to my programs binary code (for example by changing a static array with dummy data included in the program), so that the CRC16 gives my predefined value?
Can this byte sequence be included anywhere in the code or does it have to be exactly at the end?
(If necessary, I could also implement another checksum algorithm besides CRC-16.)
Thanks for your answers!
Yes, easily. For your n bytes of flash, compute the CRC-16 of the first n-2 bytes, and store that CRC in the last two bytes. Those two bytes would be appended in little-endian order for a reflected CRC, and in big-endian order for a non-reflected CRC. Then the CRC-16 of the n bytes will be a constant. That constant is known as the "residue" of the CRC. For CRC's with no exclusive-or at the end, the residue is always zero. You didn't say what CRC you're using, but you can find the residues of known CRC's (before the final exclusive-or) in Greg Cook's catalog. Or you can just see what you get.

Using only part of crc32

Will using only 2 upper/lower bytes of a crc32 sum make it weaker than crc16?
Background:
I'm currently implementing a wireless protocol.
I have chunks of 64byte each, and according to
Data Length vs CRC Length
I would need at most crc16.
Using crc16 instead of crc32 would free up bandwidth for use in Forward error correction (64byte is one block in FEC).
However, my hardware is quite low powered but has hardware support for CRC32.
So my idea was to use the hardware crc32 engine and just throw away 2 of the result bytes.
I know that this is not a crc16 sum, but that does not matter because I control both sides of the transmission.
In case it matters: I can use both crc32 (poly 0x04C11DB7) or crc32c (poly 0x1EDC6F41).
Yes, it will be weaker, but only for small numbers of bit errors. You get none of the guarantees of a CRC-16 by instead taking half of a CRC-32. E.g. the number of bits in a burst that are always detectable.
What is the noise source that you are trying to protect against?

How to detect errors in CRC-protected data?

As far as I understand to check if the data with it's CRC appended to the end of it has errors, one needs to run it through the same CRC algorithm and see if the newly calculated CRC is zero.
I've tried going though this using an online CRC calculator in the following way:
Calculate CRC for 0xAABBDD (without the 0x part) - CRC16 outputs 0x8992
Calculate CRC for 0xAABBDD8992 - CRC16 outputs 0xFB4A, not 0x0000
What am I doing wrong?
The appending the CRC thing only works for "pure" CRCs without pre and post-conditioning. Most real world CRCs however have pre and post-conditioning, mainly so that the CRC of strings of zeros are not zero.
The way to check a CRC is the same as any other check value. You get a message m c where m are the message bytes and c is the check value. You are told through some other channel (most likely a standards document) that c=f(m), with some description of the function f. To check the integrity of m c, you compute f(m) and see if that is equal to c. If not, then the message and/or check value were corrupted in transit. If they are equal, then you have some degree of assurance that the message has arrived unscathed. The assurance depends on the nature of f, the number of bits in c, and the characteristics of the possible errors on the transmission channel.

Req: More specifics on how to calculate CRC of a large file

Regrettably, What is the correct way of calculating a large CRC32 is not sufficient for me to understand how to implement calculation of a crc on a file of size 1kb <= x <= 128kb. The mhash library conceals the issue, and is thus suitable and convenient for me, nevertheless, I'd like to ask you to explain how one combines many crcs into one.
Perhaps this is the wrong question (which would then be the measure of my ignorance), but specifically, how is it legitimate to prepend the crc calculated in the previous iteration to the next block to be processed? Doesn't that severely slow the overall calculation and doesn't it potentially introduce new anomalies into otherwise unsullied data? TIA
There is no prepending. The usual approach is for the CRC routine to take the running CRC at the end of the last block as the starting CRC for the next block. I.e. crc = crc32(crc, buf, len);. The first time it's called the initial CRC is (usually) zero, so crc = crc32(0, firstbuf, firstlen);.
If you want to calculate the CRC over multiple cores, then a more involved procedure is needed to combine CRCs that were all calculated in parallel with zero as the starting point, but you want the result to be as if the CRCs were done in series with the appropriate starting points. zlib provides the crc32_combine() routine for this purpose. See the zlib manual for more information.