0
\$\begingroup\$

I have been attempting to understand the CRC calculation. I have found online CRC calulator and I have done an experiment.

I have tried to calculate with this calculator the CRC16-CCITT (in the calculator I have specified: seed value 0, final xor value 0) for data with length equal to one byte (namely 0x31). I expected that I receive the data byte itself i.e. 0x31. The reason for this expectation was based on the fact that CRC is basically reminder from division of polynomials. My "message" is one byte long so it is polynomial of degree 7 (in maximum) and the CRC16 polynomial is polynomial of degree 12 (according to the calculator) so the remainder from division of the polynomial with degree 7 by polynomial with degree 12 has to be polynomial of degree 7.

It was surprising for me that the calculator gave me CRC value equal to 0x2672. Can anybody explain to me the discrepancy? Thank you in advance.

\$\endgroup\$
3
  • \$\begingroup\$ Would you like to explain why do you expect to get the data byte itself back? Did you try to search how exactly is the CRC16-CCITT calculated? \$\endgroup\$ – Justme Dec 5 '20 at 18:33
  • \$\begingroup\$ @Justme thank you for your reaction. I have just attempted to explain why I had the expectation. \$\endgroup\$ – L3sek Dec 5 '20 at 18:46
  • \$\begingroup\$ Can you explain why you think it's a discrepancy? What were you expecting to happen? \$\endgroup\$ – Andy aka Dec 5 '20 at 18:53
1
\$\begingroup\$

It basically being a remainder does not mean it actually is, it just means the concept is the same, but not with traditional numbers and in decimal, but in Galois Field for base-2 numbers. But there is a simpler explanation too.

Calculating a CRC value is not simply about feeding in data, there are other specifications as well.

The value is initially preset to some pre-defined seed value. Usually this value is not zero, and very typically the initial value is all bits set to one. CRC-CCITT does not actually define this, and various implementations use different seed values. In terms of calculating CRC, it can also be thought of same as starting with a seed value of 0, but feeding two initial data bytes in to make the seed value correct.

After processing the data bytes, there is usually a final step to XOR the CRC value with a pre-defined final XOR value. It also varies between different implementations.

Other specifications differ as well, such as whether data is fed into CRC algorithm MSB or LSB first.

So here is how the algorithm works on the CRC calculator. Verified with pen-and-paper method.

0x31 is the only data byte fed in.

0x0000 is the initial CRC value.

Therefore, as this version of the algorithm runs MSB first, the CRC data must be fed in to the CRC register so that the MSB of the data is immediately processed, and the CRC bit shifts are performed to the left. Therefore, DATA xor CRC is:

0x3100 CRC register xored with data, no shift rounds yet

0x6200 After round 1
0xC400 After round 2
0x9821 After round 3
0x2063 After round 4
0x40C6 After round 5
0x818C After round 6
0x1339 After round 7
0x2672 After round 8

So the result of doing the algorithm with polynomial of 0x1021, with initial value of 0x0000, final xor of 0x0000, and processing the input data MSB first, the CRC value really is 0x2672.

\$\endgroup\$
5
  • \$\begingroup\$ thank you for your answer. I have read about the other specifications used during CRC calculation. With this knowledge in mind I have specified seed value 0, final xor value 0 in the calculator. The fact that I received CRC 0x2672 instead of 0x31 was all the more so surprising for me. What would you expect as resulting CRC in the conditions I have described? \$\endgroup\$ – L3sek Dec 5 '20 at 19:39
  • \$\begingroup\$ I added the verification to my answer. With that calculator, the expected value really is 0x2672. \$\endgroup\$ – Justme Dec 5 '20 at 20:21
  • \$\begingroup\$ The problem is in my wrong understanding of the CRC calculation process. Please can you tell me why the algorithm starts with the 0x3100 value in the CRC register and not with 0x0031? \$\endgroup\$ – L3sek Dec 5 '20 at 20:52
  • \$\begingroup\$ Second thing which I don't understand why the polynomial \$x^{16} + x^{12} + x^5 + 1\$ is coded as 0x1021? I would expect the \$x^{12} + x^5 + 1\$ polynomial for 0x1021. Thanks. \$\endgroup\$ – L3sek Dec 5 '20 at 20:59
  • \$\begingroup\$ But I already explained why 0x31 data goes to CRC register as 0x3100. If it would go to CRC register as 0x0031, then there would be 8 irrelevant non-data bits processed first, and the CRC value would then be 0x3100 after processing. And a 16-bit CRC is calculated with a polynomial of 17 bits (but it should not be asked in a comment but as a separate question), it can be figured out by reading a tutorial how CRCs work or the Wikipedia page. \$\endgroup\$ – Justme Dec 5 '20 at 21:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.