Расчет хеша Adler-32 на Ассемблере

Adler-32 - хеш-функция, разработанная Марком Адлером, хорошо известным по его работам в области компрессии данных. Этот хеш используется в библиотеке zlib, соавтором которой и является Марк Адлер. По скорости работы Adler-32 превосходит CRC32, однако уступает ей по качеству обнаружения ошибок контрольной суммы, особенно на коротких строках. Есть несколько вариантов реализации алгоритма на разных языках и с разной степенью эффективности, мой вариант на Ассемблере такой:
;-----------------------------------------------------------------------
; Функция вычисления хеша Adler-32
; by ManHunter / PCL
; http://www.manhunter.ru
;-----------------------------------------------------------------------
; Параметры:
;       lpData - указатель на строку
;       dSize  - длина строки
; На выходе:
;       EAX = полученный хеш
;-----------------------------------------------------------------------
proc    Adler32 lpData:DWORD, dSize:DWORD
        push    ebx ecx edx esi edi
 
        ; Инициализация
        mov     edi,1           ; s1 = 1
        xor     esi,esi         ; s2 = 0
 
        ; Длина строки
        cmp     [dSize],0
        je      .loc_ret
 
        mov     ebx,65521       ; base
        xor     ecx,ecx
@@:
        ; Получить символ из строки
        mov     eax,[lpData]
        movzx   eax,byte [eax+ecx]
 
        add     eax,edi         ; s1 = (s1 + buf[i]) % 65521
        xor     edx,edx
        div     ebx
        mov     edi,edx
 
        add     edx,esi         ; s2 = (s2 + s1) % 65521
        mov     eax,edx
        xor     edx,edx
        div     ebx
        mov     esi,edx
 
        ; Следующий символ
        inc     ecx
        cmp     ecx,[dSize]
        jb      @b
.loc_ret:
        mov     eax,esi        ; adler32 = (s2 << 16) + s1
        rol     eax,16
        add     eax,edi
 
        pop     edi esi edx ecx ebx
        ret
endp

Пример использования:
; Сегмент данных
section '.data' data readable writeable  
...
somedata db 'Yeah! I like Flat Assembler!',0 ; Исходные данные для хеширования
 
; Сегмент кода
section '.code' code readable executable
        ...
        ; Расчет длины строки. Для бинарных данных lstrlen лучше не использовать
        invoke  lstrlen,somedata
        ; Расчет Adler-32 
        stdcall Adler32,somedata,eax
        ; EAX = 82E0095Dh

Как указано в описании, самый эффективный по скорости способ расчета Adler-32 представлен авторским алгоритмом в исходниках библиотеки zlib. Но для небольших объемов данных вполне сгодится и приведенный выше вариант.

В приложении программа с исходным кодом, подсчитывающая хеш Adler-32 от введенной строки.
Теги:
Расчет хеша, Adler-32
Добавлено: 10 Апреля 2018 10:05:28 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...