hash算法

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 /*函数名:Hashed110 /*功 能:检测一个字符串是否被hash过111 /*返回值:如果存在,返回位置;否则,返回-1112 /************************************************************************/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 /*函数名:Hash140 /*功 能:hash一个字符串 141 /*返回值:成功,返回true;失败,返回false142 /************************************************************************/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表中没有空余的位置了,无法完成hash158       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 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值