对以下两种hash函数(FNV BKDR)做了点优化,方便用于以0结尾的短字符串进行hash,得到32位的hash值
----------------- By G-Spider
FNV hash
Fnv32_t __stdcall fnv_32a_str_c(char *str) { unsigned char *s = (unsigned char *)str; /* unsigned string */ Fnv32_t hval= 2166136261; /* * FNV-1a hash each octet in the buffer */ do { /* xor the bottom with the current octet */ hval ^= (Fnv32_t)*s; /* multiply by the 32 bit FNV magic prime mod 2^32 */ hval *= 0x01000193; }while(*s++); return hval; }
汇编1:
__declspec(naked) Fnv32_t __stdcall fnv_32a_str_asm1(char *str) { __asm{ mov edx,[esp + 4] ;str mov eax,2166136261 ;FNV1_32A_INIT ;--------------------------- A00: movzx ecx,byte ptr [edx] xor eax,ecx inc edx imul eax,16777619 ;fnv_32_prime test ecx,ecx jnz A00 ;--------------------------- retn 4 } }
汇编2:
__declspec(naked) Fnv32_t __stdcall fnv_32a_str_asm4(char *str) { __asm{ mov eax,2166136261 //;FNV1_32A_INIT mov edx,[esp + 4] //;str push esi push edi //;--------------------------- //;hval ^= (Fnv32_t)*s; //;hval *= 0x01000193; //;hval =hval * (0x01000000 +256+128+16+2+1) //;hval + = (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); //;--------------------------- A00: movzx ecx,byte ptr [edx] xor eax,ecx //;hval ^= (Fnv32_t)*s; lea esi,[eax+eax*2] //;(hval)+(hval<<1) shl eax,4 //;(hval<<4) inc edx lea edi,[eax+eax*8] //;(hval<<4) + (hval<<7) shl eax,4 add esi,eax //;(hval)+(hval<<1) +(hval<<8) shl eax,16 //;(hval<<24) add edi,eax //;(hval<<24) +(hval<<4) + (hval<<7) test ecx,ecx lea eax,[esi+edi] jnz A00 ;--------------------------- pop edi pop esi ;--------------------------- retn 4 } }
BKDR Hash
unsigned int __stdcall BKDRHash(unsigned char *str) { unsigned int seed = 131; // 31 131 1313 13131 131313 etc.. unsigned int hash = 0; do { hash = hash * seed + (*str); }while(*str++); return hash; }
汇编1:
__declspec(naked) unsigned int __stdcall BKDRHash1(unsigned char *str) { __asm{ xor eax, eax mov edx, [4+esp] A00: imul eax,131 movzx ecx, BYTE ptr [edx] inc edx add eax, ecx test ecx, ecx jne A00 ;--------------------------- retn 4 } }
汇编2:
__declspec(naked) unsigned int __stdcall BKDRHash2(unsigned char *str) { __asm{ xor eax, eax mov edx, [esp+4] A00: mov ecx, eax shl ecx, 6 add ecx, eax lea eax, [eax+ecx*2] movzx ecx ,byte ptr [edx] inc edx add eax, ecx test ecx, ecx jnz A00 ;--------------------------- retn 4 } }