逆向工程Panasonic IR Code Checksum

时间:2017-02-07 14:37:57

标签: arduino reverse-engineering checksum

我正在使用由 IR遥控器控制的 Panasonic AC Unit 。遥控器发送12 bytes

第一个5 bytes始终相同。以下6 bytes对应于空调温度,风扇,功能以及我能够自己弄清楚的其他选项。

最后一个byte是一个校验和,它以某种方式从第一个11 bytes(或从字节 6到{获得{1}})

由于我在运行时重新创建 IR代码,我需要能够为这些数据包计算校验和。我尝试了许多标准校验和算法,但都没有给出有意义的结果。

你能帮我找到用于此设备的校验和功能吗?

以下是数据包的列表,由11标头+数据和11 bytes校验和组成,我能够捕获来自设备:

1 byte

1 个答案:

答案 0 :(得分:2)

我找到了匹配所有数据的候选校验和功能,但我认为需要进一步调整,因为我怀疑幻数< / strong>我使用取决于其他,我没有正确考虑。

这是我能够逆向工程的功能:

uint8_t get_checksum(const uint8_t data[], const size_t size)
{
    assert(data);

    uint8_t checksum = 0;

    for (size_t i = 0; i < size; ++i)
    {
        checksum += (data[i] >> 4) + (data[i] & 0x0f);
    }

    checksum -= 8; /* magic number */

    return checksum;
};

替代版本:

uint8_t get_checksum(const uint8_t data[], const size_t size)
{
    assert(data);

    uint8_t checksum = 0xF8; /* magic number */

    for (size_t i = 0; i < size; ++i)
    {
        checksum += (data[i] >> 4) + (data[i] & 0x0f);
    }

    return checksum;
};

示例:

#include<stdio.h>
#include<stdint.h>
#include<assert.h>

uint8_t get_checksum(const uint8_t data[], const size_t size)
{
    assert(data);

    uint8_t checksum = 0xF8; /* magic number */

    for (size_t i = 0; i < size; ++i)
    {
        checksum += (data[i] >> 4) + (data[i] & 0x0f);
    }

    return checksum;
};

int main ()
{
    const size_t xlen = 49;
    const size_t ylen = 12;
    uint8_t v[49][12] = {
        {0x40,0x00,0x14,0x81,0x25,0x00,0xA0,0x65,0x00,0x00,0x00,0x26},
        {0x40,0x00,0x14,0x81,0x25,0x00,0xA0,0x68,0x00,0x00,0x07,0x30},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x65,0x00,0x00,0x00,0x2A},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x68,0x00,0x00,0x00,0x2D},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x68,0x00,0x00,0x02,0x2F},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x68,0x00,0x00,0x03,0x30},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x68,0x00,0x00,0x04,0x31},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x68,0x00,0x00,0x05,0x32},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x68,0x00,0x00,0x07,0x34},
        {0x40,0x00,0x14,0x81,0x25,0x04,0x28,0x69,0x00,0x00,0x01,0x2F},
        {0x40,0x00,0x14,0x81,0x25,0x04,0xA0,0x68,0x00,0x00,0x07,0x34},
        {0x40,0x00,0x14,0x81,0x25,0x08,0x9A,0x68,0x00,0x00,0x07,0x41},
        {0x40,0x00,0x14,0x81,0x25,0x08,0x9C,0x68,0x00,0x00,0x07,0x43},
        {0x40,0x00,0x14,0x81,0x25,0x08,0x9E,0x68,0x00,0x00,0x07,0x45},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA0,0x68,0x00,0x00,0x00,0x31},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA0,0x68,0x00,0x00,0x01,0x32},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA0,0x68,0x00,0x00,0x02,0x33},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA0,0x68,0x00,0x00,0x03,0x34},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA0,0x68,0x00,0x00,0x07,0x38},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA2,0x68,0x00,0x00,0x07,0x3A},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA4,0x68,0x00,0x00,0x07,0x3C},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA6,0x68,0x00,0x00,0x07,0x3E},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xA8,0x68,0x00,0x00,0x07,0x40},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xAA,0x68,0x00,0x00,0x07,0x42},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xAC,0x68,0x00,0x00,0x07,0x44},
        {0x40,0x00,0x14,0x81,0x25,0x08,0xAE,0x68,0x00,0x00,0x07,0x46},
        {0x40,0x00,0x14,0x81,0x25,0x09,0xA0,0x68,0x00,0x00,0x07,0x39},
        {0x40,0x00,0x14,0x81,0x25,0x0A,0xA0,0x68,0x00,0x00,0x07,0x3A},
        {0x40,0x00,0x14,0x81,0x25,0x0C,0xA0,0x68,0x00,0x00,0x07,0x3C},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x18,0x65,0x00,0x00,0x00,0x29},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x1A,0x65,0x00,0x00,0x00,0x2B},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x1C,0x65,0x00,0x00,0x00,0x2D},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x1E,0x65,0x00,0x00,0x00,0x2F},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x20,0x65,0x00,0x00,0x00,0x22},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x22,0x65,0x00,0x00,0x00,0x24},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x24,0x65,0x00,0x00,0x00,0x26},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x26,0x65,0x00,0x00,0x00,0x28},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x28,0x65,0x00,0x00,0x00,0x2A},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x2A,0x65,0x00,0x00,0x00,0x2C},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x2C,0x65,0x00,0x00,0x00,0x2E},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x2E,0x65,0x00,0x00,0x00,0x30},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x30,0x65,0x00,0x00,0x00,0x23},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x32,0x65,0x00,0x00,0x00,0x25},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x34,0x65,0x00,0x00,0x00,0x27},
        {0x40,0x00,0x14,0x81,0x25,0x40,0x34,0x68,0x00,0x00,0x04,0x2E},
        {0x40,0x00,0x14,0x81,0x25,0x80,0x1C,0x68,0x00,0x00,0x00,0x34},
        {0x40,0x00,0x14,0x81,0x25,0x80,0x20,0x65,0x00,0x00,0x00,0x26},
        {0x40,0x00,0x14,0x81,0x25,0xC0,0x20,0x65,0x00,0x00,0x00,0x2A},
        {0x40,0x00,0x14,0x81,0x25,0xC0,0x28,0x68,0x00,0x00,0x02,0x37}
    };

    // packet has 11 bytes, 1 byte is for the checksum
    for (size_t i = 0; i < xlen; ++i)
    {
        uint8_t checksum = get_checksum(v[i], 11);

        printf("result: %02x -- should be: %02x -- %s\n",
               checksum, v[i][ylen - 1],
               (checksum - v[i][ylen - 1] == 0 ? "OK" : "ERROR"));
    }
}

输出:

result: 26 -- should be: 26 -- OK
result: 30 -- should be: 30 -- OK
result: 2a -- should be: 2a -- OK
result: 2d -- should be: 2d -- OK
result: 2f -- should be: 2f -- OK
result: 30 -- should be: 30 -- OK
result: 31 -- should be: 31 -- OK
result: 32 -- should be: 32 -- OK
result: 34 -- should be: 34 -- OK
result: 2f -- should be: 2f -- OK
result: 34 -- should be: 34 -- OK
result: 41 -- should be: 41 -- OK
result: 43 -- should be: 43 -- OK
result: 45 -- should be: 45 -- OK
result: 31 -- should be: 31 -- OK
result: 32 -- should be: 32 -- OK
result: 33 -- should be: 33 -- OK
result: 34 -- should be: 34 -- OK
result: 38 -- should be: 38 -- OK
result: 3a -- should be: 3a -- OK
result: 3c -- should be: 3c -- OK
result: 3e -- should be: 3e -- OK
result: 40 -- should be: 40 -- OK
result: 42 -- should be: 42 -- OK
result: 44 -- should be: 44 -- OK
result: 46 -- should be: 46 -- OK
result: 39 -- should be: 39 -- OK
result: 3a -- should be: 3a -- OK
result: 3c -- should be: 3c -- OK
result: 29 -- should be: 29 -- OK
result: 2b -- should be: 2b -- OK
result: 2d -- should be: 2d -- OK
result: 2f -- should be: 2f -- OK
result: 22 -- should be: 22 -- OK
result: 24 -- should be: 24 -- OK
result: 26 -- should be: 26 -- OK
result: 28 -- should be: 28 -- OK
result: 2a -- should be: 2a -- OK
result: 2c -- should be: 2c -- OK
result: 2e -- should be: 2e -- OK
result: 30 -- should be: 30 -- OK
result: 23 -- should be: 23 -- OK
result: 25 -- should be: 25 -- OK
result: 27 -- should be: 27 -- OK
result: 2e -- should be: 2e -- OK
result: 34 -- should be: 34 -- OK
result: 26 -- should be: 26 -- OK
result: 2a -- should be: 2a -- OK
result: 37 -- should be: 37 -- OK