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 }