Определить алгоритм CRC по записанным данным

У меня есть следующие записанные пакеты команд по 32 байта каждый:

3da89fc200180010000000000000000024100001240400010000000000000000 
d427eb5a00180010000000000000000024100001240300010000000000000000 
984870ff00180010000000000000000024100001240200010000000000000000 
4ab8076100180010000000000000000024100001240100010000000000000000 
06d79cc400180010000000000000000024100001240000010000000000000000 

Предполагается, что первые 4 байта представляют собой контрольную сумму «Ethernet CRC-32» остальных 28 байтов. Я хочу создавать собственные команды, поэтому мне нужно выяснить, как рассчитать CRC.

Я попробовал любой вариант CRC32, который только мог придумать, и даже попробовал «reveng -w 32 -c» на приведенных выше данных, надеясь найти правильные настройки CRC. Не повезло. Я подозреваю, что до и, возможно, даже после расчета CRC происходит какое-то странное переупорядочение данных.

Как я могу подойти к этой проблеме? Существует ли автоматизированный способ попробовать различные варианты перестановки данных?

Вполне возможно, что эти CRC созданы на основе другой системной архитектуры, поэтому, кстати, PHP имеет 3 встроенные версии CRC: crc32, crc32b, crc32c. Возможно, стоит пройти тест, чтобы разобраться в этом. stackoverflow.com/a/62332485/2494754

NVRM 28.08.2024 17:11

Несколько советов: для поиска используйте -s для мести; Reveng ожидает, что CRC будет в конце сообщения, поэтому переместите его для подачи мести; CRC может быть заменен байтами, поэтому попробуйте поменять местами четыре байта.

Mark Adler 28.08.2024 17:25

Можете ли вы дать ссылку на документацию, которую вы цитируете?

Mark Adler 28.08.2024 17:25

Данные, показанные в вопросе, представляют собой команду «CONTINUOUS_IMAGE_DOWNLOAD_CMD» согласно ti.com/de/lit/pdf/swru599 §4.6.2.5.3. Он записан из рабочей эталонной реализации, которая, похоже, не совсем соответствует документации.

Sebastian 29.08.2024 10:16

Контрольная сумма, судя по всему, генерируется аппаратным модулем CRC: ti.com/de/lit/pdf/swru599 §22.5

Sebastian 29.08.2024 10:59

Вы можете проверить транскрипцию ваших примеров.

Mark Adler 30.08.2024 01:25
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
6
62
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Учитывая столь небольшие различия между сообщениями (изменяются только три бита), после первоначального анализа я могу сказать, что они не противоречат тому, что эти байты являются CRC. Этот вывод основан на единственном зависимом сообщении, в котором есть 3 в меняющейся шестнадцатеричной цифре. Это зависит от сообщений с 0, 1 и 2 в этой позиции. Если я возьму CRC для этого сообщения и эксклюзивное сообщение или их вместе, я получу CRC для сообщения с 3. 0x06d79cc4 ^ 0x4ab80761 ^ 0x984870ff == 0xd427eb5a.

Таким образом, предоставленные данные, какими бы они ни были, согласуются с линейной функцией над GF(2), одной из которых является CRC. Я могу использовать этот подход для вычисления этой функции для трех других возможных значений этих трех битов.

Немного детализируем математику: если я исключаю-или одно из сообщений, включая CRC, со всеми остальными, теперь у меня есть примеры CRC с нулевым начальным значением и нулевым окончательным исключающим-или. Их аннулируют. Поэтому для этого я выбираю сообщение с 0 в другой позиции. Теперь у меня есть сообщения, в которых все нули, кроме цифр 1, 2, 3 или 4. Если я исключаю новые сообщения с 1 и 2, я получаю сообщение с 3 в этой позиции. Вы обнаружите, что оно соответствует новому сообщению (с CRC) с 3 в этой позиции. Тот факт, что они совпадают, показывает, что набор не противоречит тому, что первые четыре байта являются линейной функцией над GF(2) остальных байтов.

Однако после перебора я обнаружил, что предоставленные данные не соответствуют ни одной 32-битной CRC! Если я предполагаю, что часть, для которой вычисляется CRC, представляет собой некоторое количество смежных байтов предоставленных сообщений, включая, конечно, меняющийся байт, и что предоставленный CRC имеет либо прямой, либо обратный порядок, тогда ни ни обратная CRC с использованием любого 32-битного полинома не будет работать.

Ответ принят как подходящий

Спасибо Марк за отличный вклад.

Я потратил еще некоторое время на изучение остальной части сообщения (за исключением CRC) и обнаружил, что данные упорядочены не так, как я ожидал. Это перестановка байтов. Я видел это с другим кодом TI SPI: они создают пакеты команд в виде массива uint32_t с прямым порядком байтов, но сначала настроили модуль SPI для 16-битной передачи со старшим битом.

Value: 0x00012410

Memory Address   0     1    2    3
Memory Bytes     0x10  0x24 0x01 0x00
Memory Words     0x2410     0x0001

SPI Bytes        0x24 0x10 0x00 0x01

Поэтому я поменял местами записанные пакеты, чтобы воссоздать структуру памяти, которая использовалась для расчета CRC. Чтобы это работало с местью, я также переместил CRC в конец сообщения, как рекомендовал Марк.

Переупорядоченные данные:

18001000000000000000000010240100042401000000000000000000a83dc29f
1800100000000000000000001024010003240100000000000000000027d45aeb
180010000000000000000000102401000224010000000000000000004898ff70
18001000000000000000000010240100012401000000000000000000b84a6107
18001000000000000000000010240100002401000000000000000000d706c49c

Теперь месть подтверждает, что это вполне нормальный CRC:

~/reveng-3.0.6/reveng -w 32 -s 18001000000000000000000010240100042401000000000000000000a83dc29f 1800100000000000000000001024010003240100000000000000000027d45aeb 180010000000000000000000102401000224010000000000000000004898ff70 18001000000000000000000010240100012401000000000000000000b84a6107 18001000000000000000000010240100002401000000000000000000d706c49c
width=32  poly=0x04c11db7  init=0xffffffff  refin=true  refout=true  xorout=0xffffffff  check=0xcbf43926  residue=0xdebb20e3  name = "CRC-32/ISO-HDLC"

Ага! Теперь моя программа грубого перебора тоже его находит.

Mark Adler 31.08.2024 22:50

Другие вопросы по теме