优化的两款串Hash函数

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




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值