Расчет CRC8 на Ассемблере
Контрольная сумма CRC8 применяется в основном для коротких сетевых пакетов и в микроконтроллерах. Из-за большой вероятности появления коллизий, использовать ее можно или для контроля целостности небольших объемах данных (оптимально - до 15 байт информации), или в случаях, когда возможность появления искажений исходных данных крайне мала. Алгоритм расчета CRC8 реализуется очень просто, работает очень быстро, из-за чего до сих пор находит свое применение. Первый вариант - прямой расчет.Code (Assembler) : Убрать нумерацию
- ;-----------------------------------------------------------------------
- ; Функция вычисления хеша 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
Code (Assembler) : Убрать нумерацию
- ; Таблица для расчета 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
Code (Assembler) : Убрать нумерацию
- ;-----------------------------------------------------------------------
- ; Функция вычисления хеша 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
Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- 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
Просмотров: 11814 | Комментариев: 3
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(08.08.2020 в 16:47):
Это не совсем так. Размер регистра - 32 бита, размер операнда - 8 бит. Обнуляется все, кроме содержимого AL. Конкретно в этом случае эту команду действительно можно убрать. Но очень хорошей привычкой будет всегда оставлять только нужную часть результата, независимо от используемой разрядности.
Андрей
(08.08.2020 в 14:40):
Доброго дня.
Никак не могу понять для чего на выходе из функции табличного расчета сделано так
.loc_ret:
and eax,0FFh
Ведь по сути and 0хFF над любым значением, оставит это значение неизменным.
Никак не могу понять для чего на выходе из функции табличного расчета сделано так
.loc_ret:
and eax,0FFh
Ведь по сути and 0хFF над любым значением, оставит это значение неизменным.
Добавить комментарий
Заполните форму для добавления комментария
Реально осознаешь свою ошибку только после того как носом ткнут. На лицо классическая "профдеформация". Перекладываю алгоритм под 8 битный МК, вот и заклинило. При том раза три просмотрел, перед тем как вопрос писать, но не отпускает восьмибитность. Потому и очевидного не вижу. Спасибо за пояснение.