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

 
 
> CRC32, uint32_t
toweroff
сообщение Mar 1 2015, 21:16
Сообщение #1


Гуру
******

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



Добрый день!

Нужна софтовая реализация. Не проблема, гугел их находит не задумываясь

Но из того, что я находил, даже табличная реализация считает по 1 байту

А хотелось бы найти подсчет сразу по 32 бита, не по 8. Благо мой массив данных всегда кратен 4 байтам, а аппаратного CRC на борту контроллера нет
По идее, это же должно увеличить производительность? sm.gif

UPD
что-то нашел от Интела

черт... там используются 4 таблицы из uint32_t[256]
места в оперативке нет, во флеше тоже... придется побайтно считать crying.gif
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Сергей Борщ
сообщение Mar 3 2015, 12:24
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Такс. Я разобрался. 0x8408, сдвиг вправо. За время обработки одного байта у нас предыдущее значение CRC сдвинется на 8 бит вправо. При этим "выпавшие" вправо биты проXORятся с исходным байтом. Отсюда byte ^= CRC и CRC >>= 8. Получившийся byte ^ CRC даст после всех обратных связей некий результат f(byte ^ CRC), который будет проXORен с получившимся CRC >>= 8. Это нам дает X = byte ^ CRC и CRC = (CRC >>8) ^ f(X).
f(X) получается следующим образом:
Код
0: 0000 0001 -> 0001 0001 1000 1001
1: 0000 0010 -> 0010 0011 0001 0010
2: 0000 0100 -> 0100 0110 0010 0100
3: 0000 1000 -> 1000 1100 0100 1000
4: 0001 0000 -> 0001 0000 1000 0001
5: 0010 0000 -> 0010 0001 0000 0010
6: 0100 0000 -> 0100 0010 0000 0100
7: 1000 0000 -> 1000 0100 0000 1000
                yy
                11
                54
y15 = x3 ^ x7 --+|
y14 = x2 ^ x6 ---+
y13 = x1 ^ x5
y12 = x0 ^ x4
y11 =      x3
y10 =      x2 ^ x3 ^ x7
y9  =      x1 ^ x2 ^ x6
y8  =      x0 ^ x1 ^ x5
y7  =           x0 ^ x4
y6  =                x3
y5  =                x2
y4  =                x1
y3  =                x0 ^ x3 ^ x7
y2  =                     x2 ^ x6
y1  =                     x1 ^ x5
y0  =                     x0 ^ x4
      \-----/   \-----/   \-----/
      A << 8    A << 3    A >> 4
      
      A = (X ^ (X << 4)) & 0xFF
  f(x) = (A << 8) ^ (A << 3) ^ (A >> 4)
Итого, на выходе имеем:
Код
byte ^= CRC;
uint8_t Tmp = byte ^ (byte << 4);
CRC = (CRC >> 8) ^ (Tmp << 8) ^ (Tmp << 3) ^ (Tmp >> 4);
Сошлось.

Аналогичным образом ищем f(X) для полинома 0xA001. Получается уже не так красиво:
Код
0: 0000 0001 -> 1100 0000 1100 0001
1: 0000 0010 -> 1100 0001 1000 0001
2: 0000 0100 -> 1100 0011 0000 0001
3: 0000 1000 -> 1100 0110 0000 0000
4: 0001 0000 -> 1100 1100 0000 0001
5: 0010 0000 -> 1101 1000 0000 0001
6: 0100 0000 -> 1111 0000 0000 0001
7: 1000 0000 -> 1010 0000 0000 0001

y15 =           x7 ^ x6 ^ x5 ^ x4 ^ x3 ^ x2 ^ x1 ^ x0
y14 =      x7 ^ x6 ^ x5 ^ x4 ^ x3 ^ x2 ^ x1
y13 = x7 ^ x6
y12 = x6 ^ x5
y11 = x5 ^ x4
y10 = x4 ^ x3
y9  = x3 ^ x2
y8  = x2 ^ x1
y7  = x1 ^ x0
y6  = x0
y5  = 0
y4  = 0
y3  = 0
y2  = 0
y1  = 0
y0  =               x7 ^ x6 ^ x5 ^ x4 ^ x2 ^ x1 ^ x0
То есть технически реализуемо, но сдвигов будет больше.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
SM
сообщение Mar 3 2015, 12:50
Сообщение #3


Гуру
******

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



Цитата(Сергей Борщ @ Mar 3 2015, 15:24) *
То есть технически реализуемо, но сдвигов будет больше.

Не реализуемо из-за единицы в A001. Эта единица дает близкую обратную связь (2^0 = 1) - таким образом такая схема реализуема, но только не для 8-битных входных данных, а лишь для двухбитных - а это никакой экономии не даст (для байта придется сделать 4 итерации). А вот в 8408 - младшая единица - 8 (2^3), что как раз разрешает такую реализацию для кусков данных до 8 бит включительно.

Не надо эту F(x) ИСКАТЬ! Она составляется просто из позиций единичных бит в полиноме. В первой части, до основного сдвига вправо, в XOR-ах в количествах сдвигов участвуют биты полинома от самого младшего и до последнего, перекрываемого по ширине входного слова, а во второй части, после сдвига - все биты полинома.

То есть, вот она, реализация для A001, но она не эффективна, из-за двухбитного ограничения, из-за этой самой A001
Код
static USHORT crc;
void update_CRC_A001_2bit(unsigned char byte)
{
   USHORT t;

   byte ^= crc;
   byte ^= byte << 1; // bit 0 of poly (0 + 1)
   byte &= 0x3;

   t = crc >> 2; // shift for -2 bits
   t ^= byte << 14; // bit 15 of poly (15 - 2 + 1)
   t ^= byte << 12; // bit 13 of poly (13 - 2 + 1)
   t ^= byte >> 1; // bit 0 of poly (0 - 2 +1)

   crc = t;

}

void update_CRC_A001(unsigned char byte)
{
  update_CRC_A001_2bit(byte);
  update_CRC_A001_2bit(byte>>2);
  update_CRC_A001_2bit(byte>>4);
  update_CRC_A001_2bit(byte>>6);
}


UPD:
Короче, имея на входе 0xFF, как его не ксорь со сдвигами, 0x55 не получишь... Вот поэтому, и нельзя реализовать A001 с 8-битным входом.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 3 2015, 14:06
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(SM @ Mar 3 2015, 14:50) *
Короче, имея на входе 0xFF, как его не ксорь со сдвигами, 0x55 не получишь... Вот поэтому, и нельзя реализовать A001 с 8-битным входом.
Не, как говорит один коллега, "не вкуриваю". У 0x1021 тоже единица в младшем разряде, но для него формула есть и работает.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
SM
сообщение Mar 3 2015, 14:23
Сообщение #5


Гуру
******

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



Цитата(Сергей Борщ @ Mar 3 2015, 17:06) *
Не, как говорит один коллега, "не вкуриваю". У 0x1021 тоже единица в младшем разряде, но для него формула есть и работает.

А там вся хитрость в том, что сдвиг-то в обратную сторону. А если все привести к сдвигу вправо... Получим знакомый 0x8408! То есть, для влево двигающихся CRC, ограничение вводит близость самого старшего бита полинома, установленного в 1, к старшему разряду. А для вправо двигающихся - младшей 1 к младшему оазряду.
То есть, 0x8408 - это 0x1021, но через зад. То есть, это один и тот же полином, реализации разные.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 3 2015, 16:05
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(SM @ Mar 3 2015, 16:23) *
То есть, 0x8408 - это 0x1021, но через зад.
Да, пока домой ехал сам понял.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- toweroff   CRC32   Mar 1 2015, 21:16
- - VAI   Вот 2 функции, одна "железная" для STM32...   Mar 2 2015, 05:49
- - toweroff   Спасибо! У меня не STM и не старшие кортексы ...   Mar 2 2015, 06:50
|- - blackfin   Цитата(toweroff @ Mar 2 2015, 09:50) Эта ...   Mar 2 2015, 07:05
|- - toweroff   Цитата(blackfin @ Mar 2 2015, 10:05) Там,...   Mar 2 2015, 07:32
- - ViKo   А вы перешлите второй раз прошивку для верификации...   Mar 2 2015, 08:14
|- - toweroff   Цитата(ViKo @ Mar 2 2015, 11:14) А вы пер...   Mar 2 2015, 10:48
|- - VAI   Цитата(ViKo @ Mar 2 2015, 12:14) А вы пер...   Mar 2 2015, 11:02
|- - toweroff   Цитата(VAI @ Mar 2 2015, 14:02) Запись же...   Mar 2 2015, 11:20
- - adnega   Типичный кусок кода для бестабличного вычисления: ...   Mar 2 2015, 11:12
|- - jcxz   Цитата(adnega @ Mar 2 2015, 17:12) Типичн...   Mar 2 2015, 11:38
|- - toweroff   Цитата(jcxz @ Mar 2 2015, 14:38) У нас бу...   Mar 2 2015, 11:55
|- - Сергей Борщ   Цитата(jcxz @ Mar 2 2015, 13:38) Также мо...   Mar 2 2015, 14:48
|- - jcxz   Цитата(Сергей Борщ @ Mar 2 2015, 20:48) Я...   Mar 2 2015, 14:55
|- - Сергей Борщ   Цитата(jcxz @ Mar 2 2015, 16:55) Я как ра...   Mar 2 2015, 16:16
- - ViKo   Кусками или целиком - какая разница? Сначала запис...   Mar 2 2015, 11:18
- - SM   Для CRC-32 такие конструкции категорически не выго...   Mar 2 2015, 17:13
|- - Сергей Борщ   Цитата(SM @ Mar 2 2015, 19:13) Для CRC-32...   Mar 3 2015, 07:54
|- - SM   Цитата(Сергей Борщ @ Mar 3 2015, 10:54) о...   Mar 3 2015, 08:11
|- - Сергей Борщ   Цитата(SM @ Mar 3 2015, 10:11) Это что зн...   Mar 3 2015, 09:08
- - SM   в общем, объясню на примере 0x8408: 1) byte ^= cr...   Mar 3 2015, 10:49
- - toweroff   Подниму тему вот по какому вопросу Когда пользова...   Mar 11 2015, 18:34
|- - SM   Цитата(toweroff @ Mar 11 2015, 21:34) но ...   Mar 11 2015, 18:49
- - toweroff   Да суть-то не в этом - с нулем или константой срав...   Mar 11 2015, 18:58
|- - SM   Цитата(toweroff @ Mar 11 2015, 21:58) Есл...   Mar 11 2015, 19:04
|- - toweroff   Цитата(SM @ Mar 11 2015, 22:04) Эту конст...   Mar 11 2015, 19:32
|- - SM   Цитата(toweroff @ Mar 11 2015, 22:32) хмм...   Mar 11 2015, 19:42
- - toweroff   Так. Не получается у меня, или я не так понял. [...   Mar 11 2015, 20:12
|- - SM   Цитата(toweroff @ Mar 11 2015, 23:12) рас...   Mar 12 2015, 08:45
- - ViKo   Пользуюсь аппаратным CRC32 в STM32, никаких перест...   Mar 12 2015, 03:51
|- - toweroff   Цитата(ViKo @ Mar 12 2015, 06:51) Пользую...   Mar 12 2015, 04:48
- - ViKo   В аппаратном CRC STM32 перед началом расчета нужно...   Mar 12 2015, 06:16
- - toweroff   Вот о чем я и говорил - если не инвертировать, то ...   Mar 12 2015, 09:58
|- - SM   Цитата(toweroff @ Mar 12 2015, 12:58) Вот...   Mar 12 2015, 10:02
- - toweroff   Просто может возникнуть необходимость проверить ...   Mar 12 2015, 11:09


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

 


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


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