Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как дополнить данные до нулевой CRC?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
ViKo
Вот здесь тренируюсь:
http://crccalc.com/

Почитал здесь для просветления в тонких местах:
https://ru.wikipedia.org/wiki/%D0%A6%D0%B8%...%BA%D0%BE%D0%B4

Ввожу число: 00000000 Hex, вычисляю CRC-32. Для CRC-32/MPEG-2 вижу результат 0xC704DD7B.
Добавляю его к данным: 00000000 C704DD7B
Вычисляю, получаю CRC-32/MPEG-2 0x00000000.
Здесь все понятно, поскольку биты входных данных и результата не реверсируются и выход не инвертируется. С инверсией выхода тоже понятно.

А как дополнить данные, если делается реверс битов? Что добавить к данным 00000000, чтобы результат стал 0x00000000? Что-то не получается.

Разобрался. Для RefIn true, RefOut true, XorOut 0xFFFFFFFF нужно CRC инвертировать и изменить порядок байтов (не битов!).

Для 00000001 CRC-32 = 0x5643EF8A, инверсия: 0xA9BC1075, перестановка байтов: 0x7510BCA9
Для 00000001 7510BCA9 CRC-32 = 0xFFFFFFFF

Почему так? Нет ли ошибки в расчетах на сайте?

Данные можно задавать в поле в таком виде:
00 00 00 01
По байтам. Ничего не меняется.
Ага, значит, CRC работает с байтами. Поэтому результат CRC нужно просто разбить на байты. Но почему тогда CRC без реверса битов не требует перестановки байтов?
k155la3
>> Ага, значит, CRC работает с байтами.
Вообще, CRC работает с битами. Потомукак реализован в виде сдвигового регистра.
Если считается CRC фрейма в канале связи/контроллере, то там байтов еще не наблюдается.
Настройки заключаются в том как байты или слова различной разрядности преобразуются в этот битовый поток.
ps - табличное вычисление - понятно, что это соптимизированный алгоритм.
ViKo
Я соображаю, как рассчитывается CRC, однако реализация алгоритма может быть разной.
В STM32 загружается 32-битовое слово и получается 32-битовый результат. Как оно внутри процессора перемалывается, мне неведомо и неважно. Мне надо знать, какое слово подать, чтобы CRC обнулить.
Serge V Iz
CRCn- это остаток от деления на неприводимый многочлен степени n над GF(2). Чтобы получить нулевую CRC, можно взять значение CRC исходного сообщения, дописать к нему n нулей, вычислить CRC от получившегося короткого сообщения длины 2n и эту новую CRC вычесть ("исключающее или" sm.gif ) из этого самого короткого сообщения в 2n разрядов. Вот в случае MPEG это самое и проделано )

Если в конце CRC инвертируется, то ее нужно обратно инвертировпть (вот это вот самое
Цитата
XorOut 0xFFFFFFFF
)
А порядок байтов, это, вероятно, из-за little endian - как оно будет выглядеть в памяти, если его записать 32-р числом вслед за строкой байтов? )
ViKo
Цитата(Serge V Iz @ May 16 2018, 20:09) *
А порядок байтов, это, вероятно, из-за little endian - как оно будет выглядеть в памяти, если его записать 32-р числом вслед за строкой байтов? )

Да, правильно. Не так я задавал числа в первом сообщении.

Вот последовательность для CRC-32/JAMCRC:

00000000 01000000 02000000 03000000 CRC-32/JAMCRC = 0xD8715056
00000000 01000000 02000000 03000000 565071D8 CRC-32/JAMCRC = 0x00000000

Т.е., добавляю то же число, посчитанную CRC, просто в окне нужно задавать данные, расположенные по байтам в памяти (little-endian).

В STM32 в функции вычисления CRC реверсирую биты входных данных, аналогично задаю массив:
uint32_t Num[] = { [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 0xD8715056 };
И вычисляется в результате 0x00000000.
Xor выходную не использую.
toweroff
А для чего это?
для сверки какая разница - ноль или не ноль...
для совсем надежности - два разных алгоритма, тогда подбор "до нуля" теряет смысл, слишком много комбинаций. Тем более, если все место занято именно исполняемым кодом, а не некритичными данными
ViKo
Цитата(toweroff @ May 16 2018, 21:18) *
А для чего это?
для сверки какая разница - ноль или не ноль...
для совсем надежности - два разных алгоритма, тогда подбор "до нуля" теряет смысл, слишком много комбинаций. Тем более, если все место занято именно исполняемым кодом, а не некритичными данными

Не понял, про какой ноль идет речь.
Задача простая. К структуре данных в микроконтроллере по вычисленной CRC данных добавить CRC-дополнение для контроля целостности. Потом, вычисляя CRC "структуры, дополненной CRC" получу результат 0x00000000 или 0xFFFFFFFF (если инверсию на выходе сделаю).
Есть значения элементов структуры по умолчанию. Вот для них хочу вычислить CRC онлайн калькулятором, но таким алгоритмом, чтобы совпадал с функцией внутри микроконтроллера. И сразу забить их в исходный код программы.

Для показанного онлайн калькулятора нашел дополнения для всех CRC. Но остаюсь в недоумении.
Если инверсия выхода не делается, то биты CRC данных в дополнении не инвертируются. Это понятно.
Если реверс входных (и выходных) битов не делается, то байты дополнения задаются в порядке big-endian. Если биты реверсируются, то порядок байтов little-endian. Вот эта особенность мне непонятна!

Ну, для своей задачи я научился считать CRC. Дополняю свои данные CRC-32/JAMCRC. Вычисляю в процессоре CRC с реверсом битов. Проверил в отладчике.
toweroff
Цитата(ViKo @ May 16 2018, 22:30) *
Не понял, про какой ноль идет речь.

Теперь понятно. Просто сталкивался с модулями флеш-памяти, где умельцы модифицировали код, а потом изменением 4х байт добивались восстановления CRC32 до исходной. Показалось, что здесь решается схожая задача
ViKo
Ну, средство то же. Цель только другая.
jcxz
Цитата(ViKo @ May 16 2018, 22:30) *
Задача простая. К структуре данных в микроконтроллере по вычисленной CRC данных добавить CRC-дополнение для контроля целостности.

А какой практических смысл таких усилий? Зачем это всё?
ViKo
Цитата(jcxz @ May 17 2018, 09:17) *
А какой практических смысл таких усилий? Зачем это всё?

Структура, содержащая переменные, управляющие режимами работы прибора, находится в памяти с батарейным питанием. При включении прибора нужно проверить ее целостность.
k155la3
Цитата(jcxz @ May 17 2018, 09:17) *
А какой практических смысл таких усилий? Зачем это всё?
когда надо экономить наносекунды при получении информаци - скоростные коммутаторы пакетов итп. и аппаратной реализации.
mcheb
Цитата(toweroff @ May 17 2018, 06:43) *
Теперь понятно. Просто сталкивался с модулями флеш-памяти, где умельцы модифицировали код, а потом изменением 4х байт добивались восстановления CRC32 до исходной. Показалось, что здесь решается схожая задача

А поподробней можно?
jcxz
Цитата(ViKo @ May 17 2018, 10:11) *
Структура, содержащая переменные, управляющие режимами работы прибора, находится в памяти с батарейным питанием. При включении прибора нужно проверить ее целостность.

Я не спрашиваю "зачем Вам CRC?" Я спрашиваю "Чем не устраивает простая операция == для проверки правильности CRC?"

Цитата(k155la3 @ May 17 2018, 10:17) *
когда надо экономить наносекунды при получении информаци - скоростные коммутаторы пакетов итп. и аппаратной реализации.

Ничего не понял.... wacko.gif
Почему не:
Код
struct DataFrame {
  ...
  u32 crc;
} data;
if (CRC32(&data, sizeof(data) - sizeof(data.crc), ~0) == data.crc) printf("CRC OK");
else printf("Bad CRC");

???
ViKo
Цитата(jcxz @ May 17 2018, 13:09) *
Я не спрашиваю "зачем Вам CRC?" Я спрашиваю "Чем не устраивает простая операция == для проверки правильности CRC?"

Так бы и говорили. biggrin.gif
А чем ваша операция лучше? CRC все равно нужно хранить. Так почему бы не хранить ее такой, что при проверке структуры вместе с CRC получится 0? Небось, на ноль проверять приятнее.
if (!(CRC32(&data, sizeof(data))) printf("CRC OK");
jcxz
Цитата(ViKo @ May 17 2018, 13:14) *
А чем ваша операция лучше? CRC все равно нужно хранить. Так почему бы не хранить ее такой, что при проверке структуры вместе с CRC получится 0? Небось, на ноль проверять приятнее.

Может и приятнее, но тратить кучу своего времени на поиски методов вычисления ради такой ерунды как экономия пары байт на сравнении с 0 я бы не стал.
Ну только если уж совсем заняться нечем biggrin.gif
ViKo
Цитата(jcxz @ May 17 2018, 13:18) *
Может и приятнее, но тратить кучу своего времени на поиски методов вычисления ради такой ерунды как экономия пары байт на сравнении с 0 я бы не стал.
Ну только если уж совсем заняться нечем biggrin.gif

Учили в школе, что данные, дополненные их же CRC, в результате дают 0. Автоматом. Тут не нужно тратить никакую кучу. Но эти манипуляции с перестановкой и инверсией битов потребовали день экспериментов. Все, вопрос решен окончательно. rolleyes.gif
toweroff
Цитата(mcheb @ May 17 2018, 11:15) *
А поподробней можно?

Что именно?
k155la3
Цитата(jcxz @ May 17 2018, 13:13) *
Ничего не понял.... Почему не . . .
При приеме "битового" потока (фрейм из канала связи или например с дискового накопителя), параллельно с заполнением буфера идет подсчет в сдвиговом регистре CRC. Для контроля целостности пакета достаточно после прихода фрейма проверить содержимое рег.CRC на 0x0000. (тк фрейм "закрывается" байтами-битами CRC).
Соотв-но нет никаких доп. операций копирования, сравнения итп. (проверка на 0 выполняется в любом случае быстрее).
ps - Это имеет смысл только для скоростной аппаратной реализации.
Serge V Iz
Да и в программной меньше букв писать.

Только если выходная добавленная к сообщению CRC инвертируется, в результате получается не ноль, а CRC(0xffffffff). Которая, впрочем, тоже константа, ничем не хуже 0 )
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.