哈希-------开放寻址法-------暴雪哈希

 1 //StringHash.h
 2 
 3 #ifndef __STRINGHASH__                                                                                             
 4 #define __STRINGHASH__
 5 
 6 #define MAXTABLELEN 1024 //默认哈希索引表大小
 7 
 8 //哈希索引表定义
 9 typedef struct _HASHTABLE
10 {
11     long nHashA; 
12     long nHashB; 
13     bool bExists;
14 }HASHTABLE, *PHASHTABLE;
15 
16 class StringHash
17 {
18     private:
19         unsigned long cryptTable[0x500];
20         unsigned long m_tablelength;
21         HASHTABLE *m_HashIndexTable;
22     
23     private:
24         InitCryptTable(); //对哈希索引表预处理
25 
26         unsigned long HashString(const char* lpszString, unsigned long dwHashType); //求取哈希值
27     
28     public: 
29         StringHash(const long nTableLength = MAXTABLELEN);
30         ~StringHash(void);
31 
32         bool Hash(const char* url);
33         unsigned long Hashed(const char* url); //检测url是否被hash过
34 };
35 
36 #endif

 

  1 //StringHash.cpp
  2 
  3 #include <StringHash.h>                                                                                            
  4 
  5 StringHash::StringHash(const long nTableLength)
  6 {
  7     InitCryptTable();
  8     m_tablelength = nTableLength;
  9 
 10     //初始化hash表
 11     m_HashIndexTabel = new HASHTABLE[nTableLength];
 12     for(int i = 0; i < nTableLength; i++)
 13     {
 14         m_HashIndexTable[i].nHashA = -1;
 15         m_HashIndexTable[i].nHashB = -1;
 16         m_HashIndexTable[i].bExists = false;
 17     }
 18 }
 19 
 20 StringHash::~StringHash(void)
 21 {
 22     //清理内存
 23     if(NULL != m_HashIndexTable)
 24     {
 25         delete []m_HashIndexTable;
 26         m_HashIndexTable = NULL; 
 27         m_tablelength = 0;
 28     }
 29 }
 30 
 31 /*
 32  *函数名:InitCryptTable
 33  *功  能:对哈希索引表预处理
 34  *返回值:无
 35  */
 36 void StringHash::InitCryptTable(void)
 37 {
 38     unsigned long sedd = 0x00100001,
 39                   index1 = 0,
 40                   index2 = 0,
 41                   i = 0;  
 42     for(index1 = 0; index1 < 0x100; index1++)
 43     {
 44         for(index2 = index1, i = 0; i < 5; i++, index2 += 0x100)
 45         {
 46             unsigned long temp1, temp2;
 47             seed = (seed * 125 + 3) % 0X2AAAAB;
 48             temp1 = (seed & 0XFFFF) << 0X10;
 49             seed = (seed * 125 + 3) % 0X2AAAAB;
 50             temp2 = (seed & 0XFFFF);
 51             cryptTable[index2] = (temp1 | temp2);
 52         }
 53     }
 54 }
 55 
 56 /*
 57  *函数名:HashString
 58  *功  能:求取哈希值
 59  *返回值:返回hash值
 60  */
 61 unsigned long StringHash::HashString(const char* lpszString, unsigned long dwHashType)
 62 {
 63     unsigned char* key = lpszString;
 64     unsigned long seed1 = 0X7FED7FED,
 65                   seed2 = 0XEEEEEEEE;
 66     int ch = 0;
 67     while(*key != 0)
 68     {
 69         ch = toupper(*key++);
 70         seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);
 71         seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
 72     }
 73     return seed1;
 74 }
 75 
 76 /*
 77  *函数名:Hashed
 78  *功  能:检测一个字符串是否被hash过
 79  *返回值:如果存在,返回位置;否则,返回-1
 80  */
 81 unsigned long StringHash::Hashed(const char* lpszString)
 82 {
 83     const unsigned long HASH__OFFSET = 0, HASH_A = 1, HASH_B = 2;
 84     //不同的字符串三次hash还会碰撞的概率无限接近于0
 85     unsigned long nHash = HashString(lpszString, HASH_OFFSET);
 86     unsigned long nHashA = HashString(lpszString, HASH_A);
 87     unsigned long nHashB = HashString(lpszString, HASH_B);
 88     unsigned long nHashStart = nHash % m_tablelength;
 89     unsigned long nHashPos = nHashStart;
 90 
 91     while(m_HashIndexTable[nHashPos].bExists)
 92     {
 93         if(m_HashIndexTable[nHashPos].nHashA == nHashA &&
 94            m_HashIndexTable[nHashPos].nHashB == nHashB)
 95             return nHashPos;
 96         else
 97             nHashPos = (nHashPos + 1) % m_tablelength;
 98 
 99         if(nHashPos == nHashStart)
100             break;
101     }
102 
103     return -1;
104 }
105 
106 /*
107  *函数名:Hash
108  *功  能:hash一个字符串
109  *返回值:成功,返回true; 失败, 返回false
110  */
111 bool StringHash::Hash(const char* lpszString)
112 {
113     const unsigned long HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2;
114     unsigned long nHash = HashString(lpszString, HASH_OFFSET);
115     unsigned long nHashA = HashString(lpszString, HASH_A);
116     unsigned long nHashB = HashString(lpszString, HASH_B);
117     unsigned long nHashStart = nHash % m_tablelength;
118     unsigned long nHashPos = nHashStart;
119 
120     while(m_HashIndexTable[nHashPos].bExists)
121     { 
122         nHashPos = (nHashPos + 1) % m_tablelength;
123         if(nHashPos == nHashStart) //一个轮回
124         {
125             //hash表中没有空余的位置了,无法完成hash
126             return false;
127         }
128     }
129 
130     m_HashIndexTable[nHashPos].bExists = true;
131     m_HashIndexTable[nHashPos].nHashA = nHashA;
132     m_HashIndexTable[nHashPos].nHashB = nHashB;
133 
134     return true;
135 }                               

 

posted on 2013-07-06 18:17  阿加  阅读(1073)  评论(0编辑  收藏  举报

导航