Blog. Just Blog

Алгоритм хеширования XXHash32 на Ассемблере

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Алгоритм хеширования XXHash32 на Ассемблере
Алгоритм хеширования XXHash32 на Ассемблере

xxHash32 - это быстрая некриптографическая хеш-функция, генерирующая 32-битный хеш. Ее автор - Yann Collet, разработчик библиотеки xxHash, также широко известный как создатель высокоскоростного алгоритма сжатия LZ4. Сам xxHash представляет собой чрезвычайно быстрый хеш-алгоритм, работающий практически на пределе скорости доступа к оперативной памяти. Существует несколько его вариантов: XXH32, XXH64, а также более современные XXH3_64bits и XXH3_128bits. В данном случае речь пойдет о классическом XXHash32.

Алгоритм выделяется крайне высокой производительностью, до нескольких гигабайт в секунду на современных процессорах, при этом обеспечивая качественное распределение хеш-значений и низкую вероятность коллизий. Поддержка seed позволяет гибко управлять результатом хеширования, что особенно полезно при построении хеш-таблиц или генерации идентификаторов. Важно помнить, что XXHash32 не предназначен для криптографического использования, он не обеспечивает защиту от преднамеренных атак и не подходит для хранения паролей или цифровых подписей.

XXH32 широко используется в современных API и библиотеках, хотя и не входит в стандартные библиотеки большинства языков программирования. Обычно его подключают через популярные сторонние пакеты. По качеству хеша, равномерности распределения и устойчивости к простым паттернам, он сопоставим с такими решениями, как MurmurHash или SipHash, и другими "быстрыми" некриптографическими хешами. При этом XXH32 выигрывает за счет простоты реализации, хорошо проанализированного, предсказуемого поведения и поддержки начального значения (seed), что позволяет гибко управлять результатом хеширования, например, для изоляции хеш-таблиц или генерации разных хешей из одних и тех же данных.
  1. ;---------------------------------------------
  2. ; Функция вычисления хеша XXHash32
  3. ;---------------------------------------------
  4. ; Параметры:
  5. ;      lpData - указатель на строку
  6. ;      dSize  - длина строки
  7. ;      dSeed  - параметр инициализации
  8. ; На выходе:
  9. ;       EAX = полученный хеш
  10. ;---------------------------------------------
  11. proc    XXHash32 lpData:DWORD, dSize:DWORD, dSeed:DWORD
  12.         ; 32-битные константы XXHash32
  13.         PRIME32_1 = 0x9E3779B1
  14.         PRIME32_2 = 0x85EBCA77
  15.         PRIME32_3 = 0xC2B2AE3D
  16.         PRIME32_4 = 0x27D4EB2F
  17.         PRIME32_5 = 0x165667B1
  18.  
  19.         push    esi edi ebx ecx edx
  20.  
  21.         mov     esi,[lpData]
  22.         mov     ecx,[dSize]
  23.         mov     edx,[dSeed]
  24.  
  25.         mov     eax,edx
  26.         add     eax,PRIME32_5
  27.         add     eax,ecx
  28.  
  29.         cmp     ecx,16
  30.         jb      .loc_skip_main
  31.  
  32.         ; Инициализация 4-х аккумуляторов
  33.         mov     eax,edx
  34.         add     eax,PRIME32_1
  35.         add     eax,PRIME32_2
  36.         mov     ebx,edx
  37.         add     ebx,PRIME32_2
  38.         mov     edi,edx
  39.         sub     edi,PRIME32_1
  40.         mov     ebp,edx
  41.         sub     ebp,PRIME32_2
  42.  
  43. .loc_loop:
  44.         cmp     ecx,16
  45.         jb      .loc_after_main
  46.  
  47.         ; Aккумуляторов 1
  48.         mov     edx,[esi]
  49.         imul    edx,PRIME32_2
  50.         add     eax,edx
  51.         rol     eax,13
  52.         imul    eax,PRIME32_1
  53.  
  54.         ; Aккумуляторов 2
  55.         mov     edx,[esi+4]
  56.         imul    edx,PRIME32_2
  57.         add     ebx,edx
  58.         rol     ebx,13
  59.         imul    ebx,PRIME32_1
  60.  
  61.         ; Aккумуляторов 3
  62.         mov     edx,[esi+8]
  63.         imul    edx,PRIME32_2
  64.         add     edi,edx
  65.         rol     edi,13
  66.         imul    edi,PRIME32_1
  67.  
  68.         ; Aккумуляторов 4
  69.         mov     edx,[esi+12]
  70.         imul    edx,PRIME32_2
  71.         add     ebp,edx
  72.         rol     ebp,13
  73.         imul    ebp,PRIME32_1
  74.  
  75.         add     esi,16
  76.         sub     ecx,16
  77.         jmp     .loc_loop
  78.  
  79. .loc_after_main:
  80.         rol     eax,1
  81.         mov     edx,ebx
  82.         rol     edx,7
  83.         add     eax,edx
  84.         mov     edx,edi
  85.         rol     edx,12
  86.         add     eax,edx
  87.         mov     edx,ebp
  88.         rol     edx,18
  89.         add     eax,edx
  90.  
  91.         ; Обработка 4‑байтных кусков
  92. .loc_skip_main:
  93.         cmp     ecx,4
  94.         jb      .loc_tail
  95.         mov     edx,[esi]
  96.         imul    edx,PRIME32_3
  97.         add     eax,edx
  98.         rol     eax,17
  99.         imul    eax,PRIME32_4
  100.         add     esi,4
  101.         sub     ecx,4
  102.         jmp     .loc_skip_main
  103.  
  104.         ; Обработка оставшихся байт
  105. .loc_tail:
  106.         cmp     ecx,0
  107.         je      .loc_final
  108.         movzx   edx,byte [esi]
  109.         imul    edx,PRIME32_5
  110.         add     eax,edx
  111.         rol     eax,11
  112.         imul    eax,PRIME32_1
  113.         inc     esi
  114.         dec     ecx
  115.         jmp     .loc_tail
  116.  
  117. .loc_final:
  118.         ; Финальная лавина
  119.         mov     edx,eax
  120.         shr     edx,15
  121.         xor     eax,edx
  122.         imul    eax,PRIME32_2
  123.  
  124.         mov     edx,eax
  125.         shr     edx,13
  126.         xor     eax,edx
  127.         imul    eax,PRIME32_3
  128.  
  129.         mov     edx,eax
  130.         shr     edx,16
  131.         xor     eax,edx
  132.  
  133.         pop     edx ecx ebx edi esi
  134.  
  135.         pop     ebp
  136.         retn
  137. endp
Функция принимает три параметра: lpData - указатель на входную строку (DWORD), dSize - ее длина в байтах, dSeed - параметр инициализации (seed). Результат возвращается в регистре EAX как 32-битное хеш-значение.

Интересный факт: константы, используемые в XXHash32, например, 0x9E3779B1 и 0x85EBCA77, традиционно используются в теории хеширования как "золотые" числа. Это значение связано с золотым сечением и специально выбрано, чтобы минимизировать систематические коллизии при хешировании последовательных ключей, целых чисел или регулярных паттернов. Комбинация нескольких подобных констант на разных этапах алгоритма - основном цикле, обработке хвоста и финальной "лавине", создает более хаотичное и равномерное распределение хеш-значений, что повышает общую надежность функции.

В приложении пример программы с исходным текстом, которая считает хеш XXHash32 для введенной строки.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

XXHash32.Demo.zip (3,174 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 271 | Комментариев: 0

Метки: Assembler, хеши

Комментарии

Отзывы посетителей сайта о статье
Комментариeв нет

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2026
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0032 сек.) / Память: 4.5 Mb
Наверх