对以下两种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
}
}