1
/*
********************************StringHash.h********************************
*/
2
3
#pragma once
4
5
#define MAXTABLELEN 1024
//
默认哈希索引表大小
6
//
7
//
哈希索引表定义
8 typedef
struct
_HASHTABLE
9
{
10
long
nHashA;
11
long
nHashB;
12
bool
bExists;
13 }HASHTABLE, *
PHASHTABLE ;
14
15
class
StringHash
16
{
17
public
:
18 StringHash(
const
long nTableLength =
MAXTABLELEN);
19 ~StringHash(
void
);
20
private
:
21 unsigned
long cryptTable[
0x500
];
22 unsigned
long m_tablelength;
//
哈希索引表长度
23 HASHTABLE *
m_HashIndexTable;
24
private
:
25
void InitCryptTable();
//
对哈希索引表预处理
26 unsigned
long HashString(
const
string& lpszString, unsigned
long dwHashType);
//
求取哈希值
27
public
:
28
bool Hash(
string
url);
29 unsigned
long Hashed(
string url);
//
检测url是否被hash过
30
};
31
32
33
34
/*
********************************StringHash.cpp********************************
*/
35
36 #include
"
StdAfx.h
"
37 #include
"
StringHash.h
"
38
39 StringHash::StringHash(
const
long nTableLength
/*
= MAXTABLELEN
*/
)
40
{
41
InitCryptTable();
42 m_tablelength =
nTableLength;
43
//
初始化hash表
44 m_HashIndexTable =
new
HASHTABLE[nTableLength];
45
for (
int i =
0; i < nTableLength; i++
)
46
{
47 m_HashIndexTable[i].nHashA = -
1
;
48 m_HashIndexTable[i].nHashB = -
1
;
49 m_HashIndexTable[i].bExists =
false
;
50
}
51
}
52
53 StringHash::~StringHash(
void
)
54
{
55
//
清理内存
56
if ( NULL !=
m_HashIndexTable )
57
{
58
delete []m_HashIndexTable;
59 m_HashIndexTable =
NULL;
60 m_tablelength =
0
;
61
}
62
}
63
64
/*
**********************************************************************
*/
65
/*
函数名:InitCryptTable
66
/*功 能:对哈希索引表预处理
67
/*返回值:无
68
/***********************************************************************
*/
69
void
StringHash::InitCryptTable()
70
{
71 unsigned
long seed =
0x00100001, index1 =
0, index2 =
0
, i;
72
73
for( index1 =
0; index1 <
0x100; index1++
)
74
{
75
for( index2 = index1, i =
0; i <
5; i++, index2 +=
0x100
)
76
{
77 unsigned
long
temp1, temp2;
78 seed = (seed *
125 +
3) %
0x2AAAAB
;
79 temp1 = (seed &
0xFFFF) <<
0x10
;
80 seed = (seed *
125 +
3) %
0x2AAAAB
;
81 temp2 = (seed &
0xFFFF
);
82 cryptTable[index2] = ( temp1 |
temp2 );
83
}
84
}
85
}
86
87
/*
**********************************************************************
*/
88
/*
函数名:HashString
89
/*功 能:求取哈希值
90
/*返回值:返回hash值
91
/***********************************************************************
*/
92 unsigned
long StringHash::HashString(
const
string& lpszString, unsigned
long
dwHashType)
93
{
94 unsigned
char *key = (unsigned
char *)(const_cast<
char*>
(lpszString.c_str()));
95 unsigned
long seed1 =
0x7FED7FED, seed2 =
0xEEEEEEEE
;
96
int
ch;
97
98
while(*key !=
0
)
99
{
100 ch = toupper(*key++
);
101
102 seed1 = cryptTable[(dwHashType <<
8) + ch] ^ (seed1 +
seed2);
103 seed2 = ch + seed1 + seed2 + (seed2 <<
5) +
3
;
104
}
105
return
seed1;
106
}
107
108
/*
**********************************************************************
*/
109
/*
函数名:Hashed
110
/*功 能:检测一个字符串是否被hash过
111
/*返回值:如果存在,返回位置;否则,返回-1
112
/***********************************************************************
*/
113 unsigned
long StringHash::Hashed(
string
lpszString)
114
115
{
116
const unsigned
long HASH_OFFSET =
0, HASH_A =
1, HASH_B =
2
;
117
//
不同的字符串三次hash还会碰撞的几率无限接近于不可能
118 unsigned
long nHash =
HashString(lpszString, HASH_OFFSET);
119 unsigned
long nHashA =
HashString(lpszString, HASH_A);
120 unsigned
long nHashB =
HashString(lpszString, HASH_B);
121 unsigned
long nHashStart = nHash %
m_tablelength,
122 nHashPos =
nHashStart;
123
124
while
( m_HashIndexTable[nHashPos].bExists)
125
{
126
if (m_HashIndexTable[nHashPos].nHashA == nHashA && m_HashIndexTable[nHashPos].nHashB ==
nHashB)
127
return
nHashPos;
128
else
129 nHashPos = (nHashPos +
1) %
m_tablelength;
130
131
if (nHashPos ==
nHashStart)
132
break
;
133
}
134
135
return -
1;
//
没有找到
136
}
137
138
/*
**********************************************************************
*/
139
/*
函数名:Hash
140
/*功 能:hash一个字符串
141
/*返回值:成功,返回true;失败,返回false
142
/***********************************************************************
*/
143
bool StringHash::Hash(
string
lpszString)
144
{
145
const unsigned
long HASH_OFFSET =
0, HASH_A =
1, HASH_B =
2
;
146 unsigned
long nHash =
HashString(lpszString, HASH_OFFSET);
147 unsigned
long nHashA =
HashString(lpszString, HASH_A);
148 unsigned
long nHashB =
HashString(lpszString, HASH_B);
149 unsigned
long nHashStart = nHash %
m_tablelength,
150 nHashPos =
nHashStart;
151
152
while
( m_HashIndexTable[nHashPos].bExists)
153
{
154 nHashPos = (nHashPos +
1) %
m_tablelength;
155
if (nHashPos == nHashStart)
//
一个轮回
156
{
157
//
hash表中没有空余的位置了,无法完成hash
158
return
false
;
159
}
160
}
161 m_HashIndexTable[nHashPos].bExists =
true
;
162 m_HashIndexTable[nHashPos].nHashA =
nHashA;
163 m_HashIndexTable[nHashPos].nHashB =
nHashB;
164
165
return
true
;
166 }
hash算法
最新推荐文章于 2024-07-27 20:52:44 发布