查找 hash/crc32 已知哈希值和原始值的算法

Find hash/crc32 algorithm with known hash value and original value

如果此类问题在这里不被允许或不合适,我深表歉意,在这种情况下请删除我的问题。

我正在尝试对两个嵌入式设备之间的协议进行逆向工程。他们发送多播 UDP 数据包。

UDP 数据包中的有效负载部分如下所示:

00000000: 00 00 00 01 5d 28 52 c5 26 30 30 3a 30 32 3a 39 |....](R.&00:02:9|
00000010: 42 3a 39 33 3a 34 41 3a 38 34 26 31 32 39 26 31 |B:93:4A:84&129&1|

我发现有效载荷部分包括

  1. 前 4 个二进制字节总是:00 00 00 01
  2. 接下来的 4 个二进制字节是某种类型的 hash/crc32(我猜)[上面:5d 28 52 c5]
  3. 纯文本中的下一个 1+17 字节是一个 MAC-地址 [以上:&00:02:9B:93:4A:84]
  4. 纯文本中接下来的 1+3 个字节是值为 128-136 的命令[以上:&129]
  5. 纯文本中接下来的 1+(1-3) 个字节是 0-254 之间的序列号[以上:&1]

MAC-address 可以是如上所示的始终不变的地址(即多播 UDP 数据包接收设备的 MAC-address)或 &FF:FF:FF: FF:FF:FF 在接收设备未知时用作广播。

广播 MAC 地址(和另一个命令值)的另一个示例如下所示:

00000000: 00 00 00 01 95 46 84 1e 26 46 46 3a 46 46 3a 46 |.....F..&FF:FF:F|
00000010: 46 3a 46 46 3a 46 46 3a 46 46 26 31 32 38 26 31 |F:FF:FF:FF&128&1|

这里的hash/crc是:95 46 84 1e

相同的 MAC 地址、相同的命令值和相同的序列号的组合在不同的 UDP 数据包中以一定的时间间隔重复,并且总是会产生相同的 hash/crc。 所以我的猜测是 hash/crc 在某种程度上只取决于 MAC 地址的值、命令值和序列号。

我试过 Slavesoft 的免费 windows hash/crc 计算器 HashCalc,但我无法获得相同的计算器 hash/crc,甚至删除了符号和冒号的任何组合。

我还尝试了一种名为 djb2 的哈希算法,发现 here and here

但是我无法弄清楚hash/crc算法,因此我需要更多知识的人的帮助。 我需要帮助才能首先找到如何根据 mac 地址、命令和序列号计算 4 字节 hash/crc 的算法。

其次,找到算法后我还需要一个实现,最好是在Python。

任何帮助将不胜感激,如果您能为我指出正确的方向以寻找和了解更多信息,我们将不胜感激。

我还有一个包含更多示例的小文件 (19 kB),但我不知道如何附加它以及是否需要它。

如果能得到所有帮助,我将不胜感激。

您可以使用 CRC RevEng 来搜索 CRC。这个结果很简单,因为它是标准的 CRC:

% ./reveng -w 32 -s 2630303a30323a39423a39333a34413a38342631323926315d2852c5   
width=32  poly=0x04c11db7  init=0xffffffff  refin=false  refout=false  xorout=0x00000000  check=0x0376e6e7  name="CRC-32/MPEG-2"

% ./reveng -w 32 -s 2646463a46463a46463a46463a46463a46462631323826319546841e
width=32  poly=0x04c11db7  init=0xffffffff  refin=false  refout=false  xorout=0x00000000  check=0x0376e6e7  name="CRC-32/MPEG-2"

这将计算 CRC:

#include <stddef.h>
#include <stdint.h>

#define POLY 0x04c11db7

/* Compute CRC of buf[0..len-1] with initial CRC crc.  This permits the
   computation of a CRC by feeding this routine a chunk of the input data at a
   time.  The value of crc for the first chunk should be 0xffffffff. */
uint32_t crc32c(uint32_t crc, const unsigned char *buf, size_t len)
{
    int k;

    while (len--) {
        crc ^= (uint32_t)(*buf++) << 24;
        for (k = 0; k < 8; k++)
            crc = crc & 0x80000000 ? (crc << 1) ^ POLY : crc << 1;
    }
    return crc;
}