Найти алгоритм hash / crc32 с известным значением хеш-функции и исходным значением

Если этот тип вопросов не разрешен или не подходит, я приношу свои извинения и в таком случае удалите мой вопрос.

Я пытаюсь реконструировать протокол между двумя встроенными устройствами. Они отправляют многоадресные 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-адрес может быть либо всегда постоянным адресом, как указано выше (являющимся MAC-адресом принимающего устройства многоадресных UDP-пакетов), либо & 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|

Здесь хэш / crc: 95 46 84 1e

Комбинация одного и того же MAC-адреса, одного и того же значения команды и одного и того же порядкового номера повторяется в разных UDP-пакетах с некоторым интервалом времени и всегда будет давать один и тот же хэш / crc. Итак, я предполагаю, что хэш / crc каким-то образом зависит только от значения MAC-адреса, значения команды и порядкового номера.

Я пробовал бесплатный калькулятор хешей / crc для Windows под названием HashCalc от Slavesoft, но не могу получить тот же хэш / crc, даже удаляя любые комбинации амперсанда и двоеточия.

Я также попробовал алгоритм хеширования под названием djb2, найденный здесь и здесь.

Но я не могу понять алгоритм hash / crc, и поэтому мне нужна помощь от кого-то более осведомленного. Мне нужна помощь, чтобы сначала найти алгоритм вычисления 4-байтового хэша / CRC на основе MAC-адреса, команды и порядкового номера.

Во-вторых, когда алгоритм найден, мне также понадобится реализация, желательно на Python.

Любая помощь была бы очень признательна, также если бы вы могли просто указать мне в правильном направлении, где искать и узнавать больше.

У меня также есть небольшой файл (19 КБ) с гораздо большим количеством примеров, но я не знаю, как его прикрепить и нужно ли.

Я был бы очень признателен за любую помощь, которую могу получить.


person Phiplex    schedule 20.02.2015    source источник
comment
Если это какой-то настраиваемый протокол, это может быть либо crc32, либо adler32, либо что-то еще, включая даже простую сумму полей. Более того, подумайте о том, чтобы взять какой-нибудь длинный хэш, скажем, SHA-1, и оставить только 32 младших бита. Вы можете только догадываться, что это такое, и найти его только по чистой случайности.   -  person Matt    schedule 20.02.2015


Ответы (1)


Вы можете использовать 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;
}
person Mark Adler    schedule 21.02.2015
comment
Вау - это фантастика - я получил ответ от Марка Адлера. Один из самых известных людей относительно crc и отец контрольной суммы Adler-32. Даже если я еще не подтвердил решение, я уверен, что это правильный ответ на мой вопрос. Я очень благодарен. - person Phiplex; 21.02.2015
comment
Я использовал реализацию Python, найденную в crc_algorithms.py, являющуюся частью pycrc, Томас Пирчер нашел здесь A Большое спасибо и ему. - person Phiplex; 21.02.2015