реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3  
Reply to this topicStart new topic
> CRC32, uint32_t
toweroff
сообщение Mar 11 2015, 19:32
Сообщение #31


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(SM @ Mar 11 2015, 22:04) *
Эту константу можно получить, обсчитав один заведомо безошибочный пакет.

хмм.. получается, что эта константа и есть именно константа? при разных данных меняться не будет?
Go to the top of the page
 
+Quote Post
SM
сообщение Mar 11 2015, 19:42
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(toweroff @ Mar 11 2015, 22:32) *
хмм.. получается, что эта константа и есть именно константа? при разных данных меняться не будет?

Да.
Короче, если проинициализировать регистр-аккумулятор CRC неким числом, и пропустить через CRC после этой инициализации это же число, но проинвертированное, по разрядности равное разрядности самой CRC, то получится всегда одна и та же константа, которая зависит только от полинома, а не от этого числа. Аналогично и с Вашим нулем - если проинициализировать регистр числом, и потом пропустить это же число, получится всегда ноль.

PS
Разумеется, это если еще и разряды не переставлены через зад в шахматном порядке, как в LCRC/ECRC PCI Express-а, например.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Mar 11 2015, 20:12
Сообщение #33


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Так.
Не получается у меня, или я не так понял.

[BODY1]
[VALID_CRC1]

[BODY2]
[VALID_CRC2]

расчет CRC32 для обоих случаев блоков [BODY1+CRC1] и [BODY2+CRC2] должен дать одинаковый результат, который есть константа для данного полинома?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Mar 12 2015, 03:51
Сообщение #34


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Пользуюсь аппаратным CRC32 в STM32, никаких перестановок битов не делаю. Дописываю ее в конец суперструктуры. При расчете CRC вместе с дописанной получаю 0.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Mar 12 2015, 04:48
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(ViKo @ Mar 12 2015, 06:51) *
Пользуюсь аппаратным CRC32 в STM32, никаких перестановок битов не делаю. Дописываю ее в конец суперструктуры. При расчете CRC вместе с дописанной получаю 0.

ну вот я тоже так думаю, что должен быть 0

взял WinHex, посчитал CRC32 сгенеренного блока. Увеличил блок на 4 байта, дописал туда эту CRC32 - не получается 0, хоть тресни! Ни инвертирование, ни замена байтов для всяких Big/Little endian не помогли. НЕ ноль и все тут
Go to the top of the page
 
+Quote Post
ViKo
сообщение Mar 12 2015, 06:16
Сообщение #36


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



В аппаратном CRC STM32 перед началом расчета нужно сбросить устройство CRC, при этом регистр CRC_DR устанавливается в 0xFFFFFFFF.
Go to the top of the page
 
+Quote Post
SM
сообщение Mar 12 2015, 08:45
Сообщение #37


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(toweroff @ Mar 11 2015, 23:12) *
расчет CRC32 для обоих случаев блоков [BODY1+CRC1] и [BODY2+CRC2] должен дать одинаковый результат, который есть константа для данного полинома?

Да. Именно так. При условии, что последовательность бит в CRC не перевернута и не переставлена. Для неинвертированной CRC - ноль. Для инвертированной - некая ненулевая константа. Ищите ошибки у себя. В WinHex, возможно, порядок следования байт неверный сделали, little/big endian, когда CRC добавляли к блоку. Или сдвиг при подсчете CRC был не в ту сторону, чтобы добавлять CRC к блоку, не переворачивая биты задом наперед.

А чтобы лучше искалось, где ошибка - вот:

CODE

#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
Go to the top of the page
 
+Quote Post
toweroff
сообщение Mar 12 2015, 09:58
Сообщение #38


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Вот о чем я и говорил - если не инвертировать, то все сходится. Но не сходится с "кошерными" результатами (которые вычисляются с инверсией начальной CRC и выходного результата) wink.gif
Go to the top of the page
 
+Quote Post
SM
сообщение Mar 12 2015, 10:02
Сообщение #39


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(toweroff @ Mar 12 2015, 12:58) *
Вот о чем я и говорил - если не инвертировать, то все сходится. Но не сходится с "кошерными" результатами

Не... Это именно, о чем я говорил - если не инвертировать, то проверять надо на ноль. Если инвертировать (кошерно) - то на 0xDEBB20E3 (для полинома 0xEDB88320). Что, по сути, без разницы - и то, и это, просто сравнение с константой, и ресурс занимает одинаковый. Вам, вообще, шашечки (чтобы константа была нулем?), или ехать (просто какая-то любая константа?)? Я даже больший секрет раскрою - значение на выходе остается константой (разумеется другой какой-то) при инверсии любого кол-ва любых бит CRC, а не только инверсии ее целиком.

А начальная инверсия, и, вообще, начальное значение, на это никак не влияют.


Добавлю. Константу, на которую надо проверять при подсчете с инверсной CRC, определить можно еще одним способом - это CRC числа ноль длиной в кол-во разрядов CRC при тех же начальных условиях (инициализации в 0xFFFFFFFF), как считается эта CRC.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Mar 12 2015, 11:09
Сообщение #40


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Просто может возникнуть необходимость проверить "на коленках" какой-то кусок данных внешними инструментами и получается, что, вроде как, сумма другая, хотя, на самом деле, - просто инвертированная
А так оно да, уже все работает и мне абсолютно фиолетово с чем сравнивать - с нулем или константой sm.gif
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 06:20
Рейтинг@Mail.ru


Страница сгенерированна за 0.01478 секунд с 7
ELECTRONIX ©2004-2016