Контрольная сумма CRC8 применяется в основном для коротких сетевых пакетов и в микроконтроллерах. Из-за большой вероятности появления коллизий, использовать ее можно или для контроля целостности небольших объемах данных (оптимально - до 15 байт информации), или в случаях, когда возможность появления искажений исходных данных крайне мала. Алгоритм расчета CRC8 реализуется очень просто, работает очень быстро, из-за чего до сих пор находит свое применение. Первый вариант - прямой расчет.
;-----------------------------------------------------------------------
; Функция вычисления хеша CRC8
; by ManHunter / PCL
; http://www.manhunter.ru
;-----------------------------------------------------------------------
; Параметры:
; lpData - указатель на строку
; dSize - длина строки
; На выходе:
; AL = полученный хеш
;-----------------------------------------------------------------------
proc CRC8 lpData:DWORD, dSize:DWORD
push ebx ecx edx esi edi
CRC8_POLYNOM = 31h
; Инициализация
mov al,0FFh
; Длина строки
cmp [dSize],0
je .loc_ret
; Указатель на начало строки
xor ecx,ecx
@@:
; Получить символ из строки
mov ebx,[lpData]
xor al,byte [ebx+ecx]
xor esi,esi
.loc_cycle:
test al,80h
jz .loc_1
shl al,1
xor al,CRC8_POLYNOM
jmp .loc_next
.loc_1:
shl al,1
.loc_next:
inc esi
cmp esi,8
jb .loc_cycle
; Следующий символ
inc ecx
cmp ecx,[dSize]
jb @b
.loc_ret:
and eax,0FFh
pop edi esi edx ecx ebx
ret
endp
Этот вариант компактный, но не самый быстрый по скорости вычисления. Более скоростной алгоритм расчета CRC8 - с использованием заранее подготовленной таблицы.
; Таблица для расчета CRC8
crc8_t db 000h, 031h, 062h, 053h, 0C4h, 0F5h, 0A6h, 097h
db 0B9h, 088h, 0DBh, 0EAh, 07Dh, 04Ch, 01Fh, 02Eh
db 043h, 072h, 021h, 010h, 087h, 0B6h, 0E5h, 0D4h
db 0FAh, 0CBh, 098h, 0A9h, 03Eh, 00Fh, 05Ch, 06Dh
db 086h, 0B7h, 0E4h, 0D5h, 042h, 073h, 020h, 011h
db 03Fh, 00Eh, 05Dh, 06Ch, 0FBh, 0CAh, 099h, 0A8h
db 0C5h, 0F4h, 0A7h, 096h, 001h, 030h, 063h, 052h
db 07Ch, 04Dh, 01Eh, 02Fh, 0B8h, 089h, 0DAh, 0EBh
db 03Dh, 00Ch, 05Fh, 06Eh, 0F9h, 0C8h, 09Bh, 0AAh
db 084h, 0B5h, 0E6h, 0D7h, 040h, 071h, 022h, 013h
db 07Eh, 04Fh, 01Ch, 02Dh, 0BAh, 08Bh, 0D8h, 0E9h
db 0C7h, 0F6h, 0A5h, 094h, 003h, 032h, 061h, 050h
db 0BBh, 08Ah, 0D9h, 0E8h, 07Fh, 04Eh, 01Dh, 02Ch
db 002h, 033h, 060h, 051h, 0C6h, 0F7h, 0A4h, 095h
db 0F8h, 0C9h, 09Ah, 0ABh, 03Ch, 00Dh, 05Eh, 06Fh
db 041h, 070h, 023h, 012h, 085h, 0B4h, 0E7h, 0D6h
db 07Ah, 04Bh, 018h, 029h, 0BEh, 08Fh, 0DCh, 0EDh
db 0C3h, 0F2h, 0A1h, 090h, 007h, 036h, 065h, 054h
db 039h, 008h, 05Bh, 06Ah, 0FDh, 0CCh, 09Fh, 0AEh
db 080h, 0B1h, 0E2h, 0D3h, 044h, 075h, 026h, 017h
db 0FCh, 0CDh, 09Eh, 0AFh, 038h, 009h, 05Ah, 06Bh
db 045h, 074h, 027h, 016h, 081h, 0B0h, 0E3h, 0D2h
db 0BFh, 08Eh, 0DDh, 0ECh, 07Bh, 04Ah, 019h, 028h
db 006h, 037h, 064h, 055h, 0C2h, 0F3h, 0A0h, 091h
db 047h, 076h, 025h, 014h, 083h, 0B2h, 0E1h, 0D0h
db 0FEh, 0CFh, 09Ch, 0ADh, 03Ah, 00Bh, 058h, 069h
db 004h, 035h, 066h, 057h, 0C0h, 0F1h, 0A2h, 093h
db 0BDh, 08Ch, 0DFh, 0EEh, 079h, 048h, 01Bh, 02Ah
db 0C1h, 0F0h, 0A3h, 092h, 005h, 034h, 067h, 056h
db 078h, 049h, 01Ah, 02Bh, 0BCh, 08Dh, 0DEh, 0EFh
db 082h, 0B3h, 0E0h, 0D1h, 046h, 077h, 024h, 015h
db 03Bh, 00Ah, 059h, 068h, 0FFh, 0CEh, 09Dh, 0ACh
Функция расчета CRC8 с помощью таблицы:
;-----------------------------------------------------------------------
; Функция вычисления хеша CRC8 с использованием таблицы
; by ManHunter / PCL
; http://www.manhunter.ru
;-----------------------------------------------------------------------
; Параметры:
; lpData - указатель на строку
; dSize - длина строки
; На выходе:
; AL = полученный хеш
;-----------------------------------------------------------------------
proc CRC8 lpData:DWORD, dSize:DWORD
push ebx ecx
; Инициализация
mov eax,0FFh
; Длина строки
cmp [dSize],0
je .loc_ret
; Указатель на начало строки
xor ecx,ecx
@@:
; Получить символ из строки
mov ebx,[lpData]
xor al,byte [ebx+ecx]
mov al,byte [crc8_t+eax]
; Следующий символ
inc ecx
cmp ecx,[dSize]
jb @b
.loc_ret:
and eax,0FFh
pop ecx ebx
ret
endp
В этом случае достигается максимальная скорость расчета, но появляются дополнительные данные в виде таблицы. Выберите нужный вам вариант расчета CRC8 в зависимости от того, что требуется для решения поставленной задачи - скорость работы или компактность кода. Пример использования:
; Сегмент данных
section '.data' data readable writeable
...
somedata db 'Yeah! I like Flat Assembler!',0 ; Исходные данные для хеширования
; Сегмент кода
section '.code' code readable executable
...
; Расчет длины строки. Для бинарных данных lstrlen лучше не использовать
invoke lstrlen,somedata
; Расчет CRC8
stdcall CRC8,somedata,eax
; AL = 0AAh
В приложении два варианта программ расчета CRC8 - с использованием таблицы и без нее.