toweroff 1 11 марта, 2015 Опубликовано 11 марта, 2015 · Жалоба Эту константу можно получить, обсчитав один заведомо безошибочный пакет. хмм.. получается, что эта константа и есть именно константа? при разных данных меняться не будет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 11 марта, 2015 Опубликовано 11 марта, 2015 · Жалоба хмм.. получается, что эта константа и есть именно константа? при разных данных меняться не будет? Да. Короче, если проинициализировать регистр-аккумулятор CRC неким числом, и пропустить через CRC после этой инициализации это же число, но проинвертированное, по разрядности равное разрядности самой CRC, то получится всегда одна и та же константа, которая зависит только от полинома, а не от этого числа. Аналогично и с Вашим нулем - если проинициализировать регистр числом, и потом пропустить это же число, получится всегда ноль. PS Разумеется, это если еще и разряды не переставлены через зад в шахматном порядке, как в LCRC/ECRC PCI Express-а, например. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 1 11 марта, 2015 Опубликовано 11 марта, 2015 · Жалоба Так. Не получается у меня, или я не так понял. [bODY1] [VALID_CRC1] [bODY2] [VALID_CRC2] расчет CRC32 для обоих случаев блоков [bODY1+CRC1] и [bODY2+CRC2] должен дать одинаковый результат, который есть константа для данного полинома? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 12 марта, 2015 Опубликовано 12 марта, 2015 · Жалоба Пользуюсь аппаратным CRC32 в STM32, никаких перестановок битов не делаю. Дописываю ее в конец суперструктуры. При расчете CRC вместе с дописанной получаю 0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 1 12 марта, 2015 Опубликовано 12 марта, 2015 · Жалоба Пользуюсь аппаратным CRC32 в STM32, никаких перестановок битов не делаю. Дописываю ее в конец суперструктуры. При расчете CRC вместе с дописанной получаю 0. ну вот я тоже так думаю, что должен быть 0 взял WinHex, посчитал CRC32 сгенеренного блока. Увеличил блок на 4 байта, дописал туда эту CRC32 - не получается 0, хоть тресни! Ни инвертирование, ни замена байтов для всяких Big/Little endian не помогли. НЕ ноль и все тут Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 12 марта, 2015 Опубликовано 12 марта, 2015 · Жалоба В аппаратном CRC STM32 перед началом расчета нужно сбросить устройство CRC, при этом регистр CRC_DR устанавливается в 0xFFFFFFFF. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 12 марта, 2015 Опубликовано 12 марта, 2015 · Жалоба расчет CRC32 для обоих случаев блоков [bODY1+CRC1] и [bODY2+CRC2] должен дать одинаковый результат, который есть константа для данного полинома? Да. Именно так. При условии, что последовательность бит в CRC не перевернута и не переставлена. Для неинвертированной CRC - ноль. Для инвертированной - некая ненулевая константа. Ищите ошибки у себя. В WinHex, возможно, порядок следования байт неверный сделали, little/big endian, когда CRC добавляли к блоку. Или сдвиг при подсчете CRC был не в ту сторону, чтобы добавлять CRC к блоку, не переворачивая биты задом наперед. А чтобы лучше искалось, где ошибка - вот: #include "memory.h" #include "stdio.h" typedef unsigned short USHORT; typedef unsigned int UINT; UINT CRC_EDB88320(char *buf, int len, UINT init) { UINT crc = init; for (int pos = 0; pos < len; pos++) { crc ^= (UINT)((unsigned char)(buf[pos])); for (int i = 8; i != 0; i--) { if ((crc & 1) != 0) { crc >>= 1; crc ^= 0xEDB88320; } else crc >>= 1; } } return crc; } int main(int argc, char* argv[]) { char data[32]; UINT crc; memcpy( data, "0123456", 7); printf ("CRC=%08X\n", crc=CRC_EDB88320(data,7,0xFFFFFFFF)); crc = ~crc; memcpy( data+7, &crc, 4); printf ("CONST=%08X\n", crc=CRC_EDB88320(data,11,0xFFFFFFFF)); memcpy( data, "235547welbxdgu", 14); printf ("CRC=%08X\n", crc=CRC_EDB88320(data,14,0xFFFFFFFF)); crc=~crc; memcpy( data+14, &crc, 4); printf ("CONST=%08X\n", crc=CRC_EDB88320(data,18,0xFFFFFFFF)); memcpy( data, "0123456", 7); printf ("CRC=%08X\n", crc=CRC_EDB88320(data,7,0xFFFFFFFF)); memcpy( data+7, &crc, 4); printf ("CONST=%08X\n", crc=CRC_EDB88320(data,11,0xFFFFFFFF)); memcpy( data, "235547welbxdgu", 14); printf ("CRC=%08X\n", crc=CRC_EDB88320(data,14,0xFFFFFFFF)); memcpy( data+14, &crc, 4); printf ("CONST=%08X\n", crc=CRC_EDB88320(data,18,0xFFFFFFFF)); return 0; } Вывод этой программы: CRC=7240F711 CONST=DEBB20E3 CRC=28E92D48 CONST=DEBB20E3 CRC=7240F711 CONST=00000000 CRC=28E92D48 CONST=00000000 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 1 12 марта, 2015 Опубликовано 12 марта, 2015 · Жалоба Вот о чем я и говорил - если не инвертировать, то все сходится. Но не сходится с "кошерными" результатами (которые вычисляются с инверсией начальной CRC и выходного результата) ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 12 марта, 2015 Опубликовано 12 марта, 2015 · Жалоба Вот о чем я и говорил - если не инвертировать, то все сходится. Но не сходится с "кошерными" результатами Не... Это именно, о чем я говорил - если не инвертировать, то проверять надо на ноль. Если инвертировать (кошерно) - то на 0xDEBB20E3 (для полинома 0xEDB88320). Что, по сути, без разницы - и то, и это, просто сравнение с константой, и ресурс занимает одинаковый. Вам, вообще, шашечки (чтобы константа была нулем?), или ехать (просто какая-то любая константа?)? Я даже больший секрет раскрою - значение на выходе остается константой (разумеется другой какой-то) при инверсии любого кол-ва любых бит CRC, а не только инверсии ее целиком. А начальная инверсия, и, вообще, начальное значение, на это никак не влияют. Добавлю. Константу, на которую надо проверять при подсчете с инверсной CRC, определить можно еще одним способом - это CRC числа ноль длиной в кол-во разрядов CRC при тех же начальных условиях (инициализации в 0xFFFFFFFF), как считается эта CRC. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 1 12 марта, 2015 Опубликовано 12 марта, 2015 · Жалоба Просто может возникнуть необходимость проверить "на коленках" какой-то кусок данных внешними инструментами и получается, что, вроде как, сумма другая, хотя, на самом деле, - просто инвертированная А так оно да, уже все работает и мне абсолютно фиолетово с чем сравнивать - с нулем или константой :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться