![Blog. Just Blog](/images/logo.png)
Расчет 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
Просмотров: 11959 | Комментариев: 3
![](/images/dot.gif)
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
![](/images/dot.gif)
ManHunter
(08.08.2020 в 16:47):
Это не совсем так. Размер регистра - 32 бита, размер операнда - 8 бит. Обнуляется все, кроме содержимого AL. Конкретно в этом случае эту команду действительно можно убрать. Но очень хорошей привычкой будет всегда оставлять только нужную часть результата, независимо от используемой разрядности.
![](/images/dot.gif)
Андрей
(08.08.2020 в 14:40):
Доброго дня.
Никак не могу понять для чего на выходе из функции табличного расчета сделано так
.loc_ret:
and eax,0FFh
Ведь по сути and 0хFF над любым значением, оставит это значение неизменным.
Никак не могу понять для чего на выходе из функции табличного расчета сделано так
.loc_ret:
and eax,0FFh
Ведь по сути and 0хFF над любым значением, оставит это значение неизменным.
![](/images/dot.gif)
Добавить комментарий
Заполните форму для добавления комментария
![](/images/dot.gif)
Реально осознаешь свою ошибку только после того как носом ткнут. На лицо классическая "профдеформация". Перекладываю алгоритм под 8 битный МК, вот и заклинило. При том раза три просмотрел, перед тем как вопрос писать, но не отпускает восьмибитность. Потому и очевидного не вижу. Спасибо за пояснение.