3

I am banging my head to figure out the checksum of a RF device, it seems to be a simple one but no luck so far...

The first 3 bytes is the SyncWord then 9 bytes is the payload and the last byte presumably is the checksum.

          +-------+-------+-------+-------+ ... +--------+--------+
          | byte0 | byte1 | byte2 | byte3 | ... | byte11 | byte12 |
          +-------+-------+-------+-------+ ... +--------+--------+
          <---- SyncWord (3) ----> <--- Payload (9) ----> <- CRC ->

It seems some kind of linear function but I cannot figure it out.

Any help will be appreciated!

Some ordered output

0xE1,0xC0,0x0A,0x0E,0xAA,0x70,0x30,0x30,0x96,0x84,0x27,0x13,0xF6
0xE1,0xC0,0x0A,0x0E,0xAA,0x60,0x30,0x30,0x96,0x84,0x27,0x13,0xE6
0xE1,0xC0,0x0A,0x4E,0x8A,0x60,0x38,0x34,0x94,0x84,0x27,0x13,0x10
0xE1,0xC0,0x0A,0x4E,0x8A,0x70,0x38,0x34,0x94,0x84,0x27,0x13,0x20
0xE1,0xC0,0x0A,0x4E,0xAA,0x60,0x30,0x34,0x94,0x84,0x27,0x13,0x28
0xE1,0xC0,0x0A,0x4E,0xAA,0x60,0x38,0x34,0x94,0x84,0x27,0x13,0x30
0xE1,0xC0,0x0A,0x4E,0xAA,0x70,0x30,0x34,0x94,0x84,0x27,0x13,0x38

0xE1,0xC0,0x0A,0x4F,0x8A,0x70,0x30,0x14,0x9C,0x81,0x25,0x12,0xFB
0xE1,0xC0,0x0A,0x4F,0xAA,0x70,0x30,0x14,0x9C,0x81,0x25,0x12,0x1B
0xE1,0xC0,0x0A,0x0E,0xAA,0x70,0x30,0x34,0x94,0x85,0x27,0x13,0xF9
0xE1,0xC0,0x0A,0x0E,0x8A,0x60,0x38,0x34,0x94,0x85,0x27,0x13,0xD1

Samples

0xE1,0xC0,0x0A,0x5F,0x8E,0x74,0x39,0x15,0x9C,0x89,0x03,0x33,0x24
0xE1,0xC0,0x0A,0x1F,0xAE,0x74,0x39,0x15,0x9C,0x89,0x03,0x33,0x04
0xE1,0xC0,0x0A,0x5F,0xAE,0x74,0x39,0x15,0x9C,0x89,0x03,0x33,0x44
0xE1,0xC0,0x0A,0x5F,0xAE,0x64,0x31,0x11,0x9E,0x89,0x03,0x33,0x2A
0xE1,0xC0,0x0A,0x1F,0x8E,0x74,0x31,0x11,0x9E,0x89,0x03,0x33,0xDA
0xE1,0xC0,0x0A,0x5F,0x8E,0x74,0x31,0x11,0x9E,0x89,0x03,0x33,0x1A
0xE1,0xC0,0x0A,0x5F,0x8E,0x64,0x39,0x11,0x9E,0x89,0x03,0x33,0x12
0xE1,0xC0,0x0A,0x1F,0xAE,0x64,0x39,0x11,0x9E,0x89,0x03,0x33,0xF2
0xE1,0xC0,0x0A,0x5F,0xAE,0x64,0x39,0x11,0x9E,0x89,0x03,0x33,0x32
0xE1,0xC0,0x0A,0x5F,0xAE,0x74,0x39,0x11,0x9E,0x89,0x03,0x33,0x42
0xE1,0xC0,0x0A,0x1F,0x8E,0x64,0x31,0x15,0x9E,0x89,0x03,0x33,0xCE
0xE1,0xC0,0x0A,0x5F,0x8E,0x64,0x31,0x15,0x9E,0x89,0x03,0x33,0x0E
0xE1,0xC0,0x0A,0x5F,0x8E,0x74,0x31,0x15,0x9E,0x89,0x03,0x33,0x1E
0xE1,0xC0,0x0A,0x1F,0xAE,0x74,0x31,0x15,0x9E,0x89,0x03,0x33,0xFE
0xE1,0xC0,0x0A,0x5F,0xAE,0x74,0x31,0x15,0x9E,0x89,0x03,0x33,0x3E
0xE1,0xC0,0x0A,0x5F,0xAE,0x64,0x39,0x15,0x9E,0x89,0x03,0x33,0x36
0xE1,0xC0,0x0A,0x1F,0x8E,0x74,0x39,0x15,0x9E,0x89,0x03,0x33,0xE6
0xE1,0xC0,0x0A,0x5F,0x8E,0x74,0x39,0x15,0x9E,0x89,0x03,0x33,0x26
0xE1,0xC0,0x0A,0x5F,0x8E,0x64,0x31,0x11,0x9C,0x88,0x03,0xB3,0x87
0xE1,0xC0,0x0A,0x1F,0xAE,0x64,0x31,0x11,0x9C,0x88,0x03,0xB3,0x67
0xE1,0xC0,0x0A,0x5F,0xAE,0x64,0x31,0x11,0x9C,0x88,0x03,0xB3,0xA7
0xE1,0xC0,0x0A,0x5F,0xAE,0x74,0x31,0x11,0x9C,0x88,0x03,0xB3,0xB7
0xE1,0xC0,0x0A,0x1F,0x8E,0x64,0x39,0x11,0x9C,0x88,0x03,0xB3,0x4F
0xE1,0xC0,0x0A,0x5F,0x8E,0x64,0x39,0x11,0x9C,0x88,0x03,0xB3,0x8F

0xE1,0xC0,0x0A,0x5E,0x0F,0x24,0x91,0x01,0x86,0x81,0x01,0x30,0x75
0xE1,0xC0,0x0A,0x1E,0x2F,0x24,0x91,0x01,0x86,0x81,0x01,0x30,0x55
0xE1,0xC0,0x0A,0x1E,0x2F,0x34,0x91,0x01,0x86,0x81,0x01,0x30,0x65
0xE1,0xC0,0x0A,0x5E,0x2F,0x34,0x91,0x01,0x86,0x81,0x01,0x30,0xA5
0xE1,0xC0,0x0A,0x1E,0x0F,0x24,0x99,0x01,0x86,0x81,0x01,0x30,0x3D
0xE1,0xC0,0x0A,0x1E,0x0F,0x34,0x99,0x01,0x86,0x81,0x01,0x30,0x4D
0xE1,0xC0,0x0A,0x5E,0x0F,0x34,0x99,0x01,0x86,0x81,0x01,0x30,0x8D
0xE1,0xC0,0x0A,0x1E,0x2F,0x34,0x99,0x01,0x86,0x81,0x01,0x30,0x6D
0xE1,0xC0,0x0A,0x1E,0x2F,0x24,0x91,0x05,0x86,0x81,0x01,0x30,0x59
0xE1,0xC0,0x0A,0x5E,0x2F,0x24,0x91,0x05,0x86,0x81,0x01,0x30,0x99
0xE1,0xC0,0x0A,0x1E,0x0F,0x34,0x91,0x05,0x86,0x81,0x01,0x30,0x49
0xE1,0xC0,0x0A,0x1E,0x0F,0x24,0x99,0x05,0x86,0x81,0x01,0x30,0x41
0xE1,0xC0,0x0A,0x5E,0x0F,0x24,0x99,0x05,0x86,0x81,0x01,0x30,0x81
0xE1,0xC0,0x0A,0x1E,0x2F,0x24,0x99,0x05,0x86,0x81,0x01,0x30,0x61
0xE1,0xC0,0x0A,0x1E,0x2F,0x34,0x99,0x05,0x86,0x81,0x01,0x30,0x71
0xE1,0xC0,0x0A,0x5E,0x2F,0x34,0x99,0x05,0x86,0x81,0x01,0x30,0xB1
0xE1,0xC0,0x0A,0x1E,0x0F,0x24,0x91,0x01,0x84,0x80,0x01,0xB0,0xB2
0xE1,0xC0,0x0A,0x1E,0x0F,0x34,0x91,0x01,0x84,0x80,0x01,0xB0,0xC2
0xE1,0xC0,0x0A,0x5E,0x0F,0x34,0x91,0x01,0x84,0x80,0x01,0xB0,0x02
0xE1,0xC0,0x0A,0x1E,0x2F,0x34,0x91,0x01,0x84,0x80,0x01,0xB0,0xE2
0xE1,0xC0,0x0A,0x1E,0x2F,0x24,0x99,0x01,0x84,0x80,0x01,0xB0,0xDA

0xE1,0xC0,0x0A,0x0F,0xAA,0x60,0x30,0x14,0x9C,0x88,0x23,0x13,0xD1
0xE1,0xC0,0x0A,0x0F,0xAA,0x70,0x30,0x14,0x9C,0x88,0x23,0x13,0xE1
0xE1,0xC0,0x0A,0x0F,0x8A,0x70,0x30,0x14,0x9C,0x88,0x23,0x13,0xC1
0xE1,0xC0,0x0A,0x0F,0x8A,0x60,0x38,0x14,0x9C,0x88,0x23,0x13,0xB9
0xE1,0xC0,0x0A,0x0F,0xAA,0x60,0x38,0x14,0x9C,0x88,0x23,0x13,0xD9
0xE1,0xC0,0x0A,0x0F,0x8A,0x70,0x38,0x14,0x9C,0x88,0x23,0x13,0xC9
0xE1,0xC0,0x0A,0x0F,0x8A,0x60,0x30,0x10,0x9E,0x88,0x23,0x13,0xAF
0xE1,0xC0,0x0A,0x4F,0xAA,0x60,0x30,0x10,0x9E,0x88,0x23,0x13,0x0F
0xE1,0xC0,0x0A,0x4F,0x8A,0x70,0x30,0x10,0x9E,0x88,0x23,0x13,0xFF
0xE1,0xC0,0x0A,0x4E,0xAA,0x60,0x30,0x34,0x94,0x84,0x27,0x13,0x28
0xE1,0xC0,0x0A,0x4E,0x8A,0x70,0x30,0x34,0x94,0x84,0x27,0x13,0x18
0xE1,0xC0,0x0A,0x4E,0xAA,0x70,0x30,0x34,0x94,0x84,0x27,0x13,0x38
0xE1,0xC0,0x0A,0x4E,0x8A,0x60,0x38,0x34,0x94,0x84,0x27,0x13,0x10
0xE1,0xC0,0x0A,0x4E,0xAA,0x60,0x38,0x34,0x94,0x84,0x27,0x13,0x30
0xE1,0xC0,0x0A,0x4E,0x8A,0x70,0x38,0x34,0x94,0x84,0x27,0x13,0x20
0xE1,0xC0,0x0A,0x4E,0x8A,0x60,0x30,0x30,0x96,0x84,0x27,0x13,0x06
0xE1,0xC0,0x0A,0x0E,0xAA,0x60,0x30,0x30,0x96,0x84,0x27,0x13,0xE6
0xE1,0xC0,0x0A,0x0E,0x8A,0x70,0x30,0x30,0x96,0x84,0x27,0x13,0xD6
0xE1,0xC0,0x0A,0x0E,0xAA,0x70,0x30,0x30,0x96,0x84,0x27,0x13,0xF6
2
  • can you extract code from the device, or is there a firmware update available? similar question about the receiving side.
    – Igor Skochinsky
    Commented May 13, 2018 at 10:28
  • 2
    Its a PIC mcu no firmware available and code protection bit enabled, receiver is the same. The rf side is a cc1101, but none of its packet control feature enabled, so they are handling everything in the pic. Commented May 13, 2018 at 14:32

1 Answer 1

6

The checksum algorithm is simple indeed. It adds all the payload bytes modulo 0xFF and then adds 26.

I wrote a script to test it:

#!/usr/bin/python

import binascii

def checksum(data):
    payload = data[3:-1]
    checksum = 26
    for c in payload:
        checksum += c
    checksum &= 0xFF
    return checksum

with open("input.txt","r") as f:
    for line in f:
        line = line.strip()
        if line == "":
            continue
        line = line.replace(",","")
        line = line.replace("0x","")

        data = binascii.unhexlify(line)

        if checksum(data) == data[-1]:
            print("pass")
        else:
            print("fail")

I copied your above samples into input.txt and they all passed.

As for how I found out, I googled about sync words (didn't know what that is), and 1 byte checksums and some other post mentioned simple addition. I also tested multiple CRC8 variants but none worked. I also found it telling that the checksum seems to reflect changes in the input, such as:

0xE1,0xC0,0x0A,0x4E,0x8A,0x60,0x38,0x34,0x94,0x84,0x27,0x13,0x10
0xE1,0xC0,0x0A,0x4E,0x8A,0x70,0x38,0x34,0x94,0x84,0x27,0x13,0x20

The 0x60 changed to 0x70 and so did the checksum increase by 0x10 which - I think - would not be as obvious for CRCs.

3
  • Thank You! I really appreciate your time, and i also tested this algorithm with slight modification and indeed works like a charm. Commented May 14, 2018 at 19:10
  • @RáczAttila what modification did you have to make?
    – Igor Skochinsky
    Commented May 15, 2018 at 6:05
  • 1
    Because i used python2.7 the binascii method not worked. I had to use data= line.split(",") and checksum += int(c,16). Commented May 15, 2018 at 7:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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