Нашел такое описание. Табличный алгоритм. Его суть состоит в следующем: при выполнении операции XOR содержимого регистра с постоянной величиной при различных её сдвигах всегда будет существовать некоторое значение, которое при применении операции XOR с исходным содержимым регистра даст тот же самый результат. А значит, можно составить таблицу таких величин, где индексом является исходное содержимое регистра. Эта таблица позволяет значительно ускорить расчёт CRC заменой восьми операций сдвига одной операцией поиска по таблице.
Всего значений в таблице 256. Поэтому при ее расчёте выполняется цикл по 256 значениям (от 0 до 255):
1.Очередной индекс помещается в регистр. Так как индекс представляет собой один байт, а величина полинома и регистра - два байта, индекс помещается в старший байт регистра, а младший байт заполнен нулями.
2. Содержимое регистра восемь раз сдвигается влево по одному биту. Каждый раз проверяется выдвинутый бит. Если из регистра был выдвинут бит со значением "1", то содержимое регистра комбинируется по XOR с полиномом. Если значение бита равно "0", XOR не выполняется.
3. Полученная двухбайтовая величина заносится в таблицу по индексу.
После того как таблица рассчитана, можно использовать табличный алгоритм CRC:
1. Сдвиг регистра на 1 байт влево с чтением нового байта сообщения.
2. XOR старшего байта, только что выдвинутого из регистра с новым байтом сообщения, что даёт индекс в таблице [0..255].
3. XOR табличного значения с содержимым регистра.
4. Если ещё есть байты данных, перейти к шагу 1.
В данной статье используется описанный выше табличный алгоритм.
Код для расчёта таблицы:
Word MakeCRC16Table(void) { Word r; for(int i=0; i<256; i++) { r = ((Word)i)<<8; for(byte j=0; j<8; j++) { if(r&(1<<15)) r=(r<<1)^0x8005; else r=r<<1; } crctable[i]=r; } } Код для расчёта CRC:
Word GetCRC16(byte *buf, Word len) { Word crc; crc = 0xFFFF; while(len--) { crc = crctable[((crc>>8)^*buf++)&0xFF] ^ (crc<<8); } crc ^= 0xFFFF; return crc; }
но это алгоритм для вычисление CRC 16 одного байта. а как высчитать CRC16 последовательности байт. есть например UDP пакет заголовок Src Port: 47202 (47202), 68:62 Dst Port: vce (11111) 26:67 Length: 28 00:1C Checksum: 0x0000 (none) 00:00 (это контрольная сумма что нужно получить) Data--11:00:48:25:be:0a:5a:0a:7f:ff:ff:ff:00:03:20:00:24:cd:ff:00
CRC=GetCRC16(0x6862, 16); CRC=CRC+GetCRC16(0x2667, 16); CRC=CRC+GetCRC16(0x001C, 16); ....
так или его нужно какие "финты ушами" делать при сложении CRC???
А вообще для CRC в UDP пакете используется полином 0x8005? аналогично для CRC в IP пакете?
|