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

 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 }                               

 

你可能感兴趣的:(哈希)