在长字符串比较或文件校验时,我们常常会用到哈希(Hash)算法,比如:CRC32、MD5、SHA1等等。但是这些算法虽然安全但是运算速度却很慢,暴雪(Blizzard)哈希是一种简单的哈希算法,但是它通过三种不同的哈希运算大大降低了哈希值重复的几率。

如果说两个不同的字符串经过一个哈希算法得到的入口点一致有可能,但用三个不同的哈希算法算出的入口点都一致,那几乎可以肯定是不可能的事了,这个几率是1:18889465931478580854784,大概是10的 22.3次方分之一,对一个程序来说足够安全了。

暴雪哈希算法的实现如下:

unsigned long g_hashCryptTable[0x500];

void InitHashCryptTable(void)
{
    unsigned long seed = 0x00100001, index1 = 0, index2 = 0, i; 
    for( index1 = 0; index1 < 0x100; index1++ ) 
    { 
        for( index2 = index1, i = 0; i < 5; i++, index2 += 0x100 ) 
        { 
            unsigned long temp1, temp2; 
            seed = (seed * 125 + 3) % 0x2AAAAB; 
            temp1 = (seed & 0xFFFF) << 0x10; 
            seed = (seed * 125 + 3) % 0x2AAAAB; 
            temp2 = (seed & 0xFFFF); 
            g_hashCryptTable[index2] = (temp1 | temp2); 
        } 
    } 
}

unsigned long HashString(char* lpszString, unsigned long dwHashType)
{
      unsigned char *key = (unsigned char *)lpszString;
    unsigned long seed1 = 0x7FED7FED, seed2 = 0xEEEEEEEE; 
    int ch;
    while(*key != 0) 
    { 
        ch = toupper(*key++);
        seed1 = g_hashCryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2); 
        seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; 
    }
    return seed1; 
}

哈希算法的使用方法如下:

const int HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2;  
int nHash = HashString(lpszString, HASH_OFFSET);  
int nHashA = HashString(lpszString, HASH_A);  
int nHashB = HashString(lpszString, HASH_B);  

在这里只提供对暴雪(Blizzard)哈希算法的封装,对哈希表的封装如果敢兴趣大家可以自己查找。

标签: 暴雪哈希, 哈希

添加新评论