Search code examples
checksumcrc16

Reverse engineering checksum from ascii string?


I'm currently working on reverse engineering a device I have serial protocol.

I'm mostly there however I can't figure out one part of the string.

For each string the machine returns it always has !XXXX where the XXXX varies in a hex value. From what I can find this may be CRC16?

However I can't figure out how to calculate the CRC myself to confirm it is correct.

Here's an example of 3 Responses.

U;0;!1F1B
U;1;!0E92
U;2;!3C09

The number can be replaced with a range of ascii characters. For example here's what I'll be using most often.

U;RYAN W;!FF0A

How do I calculate how the checksum is generated?


Solution

  • You need more examples with different lengths.

    With reveng, you will want to reverse the CRC byte, e.g. 1b1f, not 1f1b. It appears that the CRC is calculated over what is between the semicolons. With reveng I get that the polynomial is 0x1021, which is a very common 16-bit polynomial, and that the CRC is reflected.

    % reveng -w 16 -s 301b1f 31920e 32093c 5259414e20570aff
    width=16  poly=0x1021  init=0x1554  refin=true  refout=true  xorout=0x07f0  check=0xfa7e  name=(none)
    width=16  poly=0x1021  init=0xe54b  refin=true  refout=true  xorout=0xffff  check=0xfa7e  name=(none)
    

    With more examples, you will be able to determine the initial value of the CRC register and what the result is exclusive-or'ed with.