hash算法c语言代码 博客,暴雪的hash算法C语言测试版

这段代码展示了如何用C语言实现一个基于字符串的哈希算法,包括初始化哈希表、计算哈希值和处理哈希冲突。通过三次哈希确保较低的碰撞率,并提供了一个简单的测试用例。

记录一个暴雪的hash算法C语言测试版,方便以后使用

#include

#include

#include

#include

#include

#define MAXTABLELEN 102400000

typedef struct _HASHTABLE

{

long nHashA;

long nHashB;

bool bExists;

}HASHTABLE, *PHASHTABLE;

const unsigned long nTableLength = MAXTABLELEN;

unsigned long m_tablelength; // 哈希索引表长度

HASHTABLE *m_HashIndexTable;

unsigned long cryptTable[0x500];

int collc = 0;

int errstr = 0;

void InitCryptTable()

{

unsigned long seed = 0x00100001, index1 = 0, index2 = 0, i;

for( index1 = 0; index1 < 0x100; index1++ )

{

for( index2 = index1, i = 0; i < 5; i++, index2 += 0x100 )

{

unsigned long temp1, temp2;

seed = (seed * 125 + 3) % 0x2AAAAB;

temp1 = (seed & 0xFFFF) << 0x10;

seed = (seed * 125 + 3) % 0x2AAAAB;

temp2 = (seed & 0xFFFF);

cryptTable[index2] = ( temp1 | temp2 );

}

}

}

/************************************************************************/

/*函数名:HashString

*功 能:求取哈希值

*返回值:返回hash值

************************************************************************/

unsigned long HashString(char *lpszString, unsigned long dwHashType)

{

unsigned char *key = (unsigned char *)lpszString;

unsigned long seed1 = 0x7FED7FED, seed2 = 0xEEEEEEEE;

int ch;

while(*key != 0)

{

ch = toupper(*key++);

seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);

seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;

}

return seed1;

}

/************************************************************************/

/*函数名:Hashed

*功 能:检测一个字符串是否被hash过

*返回值:如果存在,返回位置;否则,返回-1

************************************************************************/

unsigned long Hashed(char * lpszString)

{

const unsigned long HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2;

//不同的字符串三次hash还会碰撞的率无限接近于不可能

unsigned long nHash = HashString(lpszString, HASH_OFFSET);

unsigned long nHashA = HashString(lpszString, HASH_A);

unsigned long nHashB = HashString(lpszString, HASH_B);

unsigned long nHashStart = nHash % m_tablelength;

unsigned long nHashPos = nHashStart;

while (m_HashIndexTable[nHashPos].bExists)

{

if (m_HashIndexTable[nHashPos].nHashA == nHashA && m_HashIndexTable[nHashPos].nHashB == nHashB)

return nHashPos;

else

nHashPos = (nHashPos + 1) % m_tablelength;

if (nHashPos == nHashStart)

break;

}

errstr++;

return -1; //没有找到

}

/************************************************************************/

/*函数名:Hash

*功 能:hash一个字符串

*返回值:成功,返回true;失败,返回false

************************************************************************/

bool Hash(char * lpszString)

{

const unsigned long HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2;

unsigned long nHash = HashString(lpszString, HASH_OFFSET);

unsigned long nHashA = HashString(lpszString, HASH_A);

unsigned long nHashB = HashString(lpszString, HASH_B);

unsigned long nHashStart = nHash % m_tablelength,

nHashPos = nHashStart;

while (m_HashIndexTable[nHashPos].bExists)

{

nHashPos = (nHashPos + 1) % m_tablelength;

if (nHashPos == nHashStart) //一个轮回

{

collc ++;

//hash表中没有空余的位置了,无法完成hash

return false;

}

}

m_HashIndexTable[nHashPos].bExists = true;

m_HashIndexTable[nHashPos].nHashA = nHashA;

m_HashIndexTable[nHashPos].nHashB = nHashB;

return true;

}

int InitHashTable()

{

int i;

InitCryptTable();

m_tablelength = nTableLength;

m_HashIndexTable = (HASHTABLE *)malloc(nTableLength * sizeof(HASHTABLE));

if (NULL == m_HashIndexTable) {

printf("Init HashTable failure!!\n");

return -1;

}

for (i = 0; i < nTableLength; i++ )

{

m_HashIndexTable[i].nHashA = 0;

m_HashIndexTable[i].nHashB = 0;

m_HashIndexTable[i].bExists = false;

}

return 0;

}

void do_test()

{

int count = 0;

FILE *fp;

char url[2048] = {0};

fp = fopen("urllist", "rb+");

if (NULL == fp) {

return;

}

if (InitHashTable()) {

return;

}

while (!feof(fp)) {

fgets(url, 2048, fp);

Hash(url);

count++;

}

printf("count: %d\n", count);

fclose(fp);

}

/*test main*/

int main()

{

do_test();

printf("conflict: %d\n", collc);

printf("not find: %d\n", errstr);

return 0;

}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值