记录几个经典的字符串hash算法
记录几个经典的字符串hash算法,方便以后查看:
推荐一篇文章:
http://www.partow.net/programming/hashfunctions/#
(1)暴雪字符串hash
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h> #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 = ;
int errstr = ; void InitCryptTable()
{
unsigned long seed = 0x00100001, index1 = , index2 = , i; for( index1 = ; index1 < 0x100; index1++ )
{
for( index2 = index1, i = ; i < ; i++, index2 += 0x100 )
{
unsigned long temp1, temp2;
seed = (seed * + ) % 0x2AAAAB;
temp1 = (seed & 0xFFFF) << 0x10;
seed = (seed * + ) % 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 != )
{
ch = toupper(*key++); seed1 = cryptTable[(dwHashType << ) + ch] ^ (seed1 + seed2);
seed2 = ch + seed1 + seed2 + (seed2 << ) + ;
}
return seed1;
}
/************************************************************************/
/*函数名:Hashed
*功 能:检测一个字符串是否被hash过
*返回值:如果存在,返回位置;否则,返回-1
************************************************************************/
unsigned long Hashed(char * lpszString) {
const unsigned long HASH_OFFSET = , HASH_A = , HASH_B = ;
//不同的字符串三次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 + ) % m_tablelength; if (nHashPos == nHashStart)
break;
}
errstr++; return -; //没有找到
} /************************************************************************/
/*函数名:Hash
*功 能:hash一个字符串
*返回值:成功,返回true;失败,返回false
************************************************************************/
bool Hash(char * lpszString)
{
const unsigned long HASH_OFFSET = , HASH_A = , HASH_B = ;
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 + ) % 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 -;
} for (i = ; i < nTableLength; i++ )
{
m_HashIndexTable[i].nHashA = ;
m_HashIndexTable[i].nHashB = ;
m_HashIndexTable[i].bExists = false;
} return ;
} void do_test()
{
int count = ;
FILE *fp;
char url[] = {}; fp = fopen("urllist", "rb+");
if (NULL == fp) {
return;
} if (InitHashTable()) {
return;
} while (!feof(fp)) {
fgets(url, , 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 ;
}
(2)字符串hash算法 ELFhash
#include <stdio.h>
#include <string.h>
#include <stdlib.h> #define MOD 10 int ELFhash(char*key)
{
unsigned long h=;
while(*key)
{
h = (h << ) + *key++;
unsigned long g = h & 0xF0000000L;
if(g)
h ^= g >> ;
h &= ~g;
}
return h % MOD;
} int main(int argc, char **argv)
{
if (argc < ) {
printf("using %s <string>\n", argv[]);
return -;
} int num = ;
num = ELFhash(argv[]); printf("num is %d\n", num);
}
记录几个经典的字符串hash算法的更多相关文章
- 字符串Hash算法比较
基本概念所谓完美哈希函数,就是指没有冲突的哈希函数,即对任意的 key1 != key2 有h(key1) != h(key2).设定义域为X,值域为Y, n=|X|,m=|Y|,那么肯定有m> ...
- 字符串hash算法
http://www.cnblogs.com/zyf0163/p/4806951.html hash函数对大家来说不陌生吧 ? 而这次我们就用hash函数来实现字符串匹配. 首先我们会想一下二进制数. ...
- HDU 1880 魔咒词典 (字符串hash)
<题目链接> 题目大意: 就是每个字符串有一个配套的对应字符串,询问的时候,无论输出其中的哪一个字符串,输出另一个,如果不存在这个字符串,直接输出"what?". 解题 ...
- Hash 算法与 Manacher 算法
目录 前言 简单介绍 简述 Hash 冲突 离散化 基本结构 普通 Hash 简述 例题 字符串 Hash 简单介绍 核心思想 基本运算 二维字符串 Hash 例题 兔子与兔子 回文子串的最大长度 后 ...
- 字符串hash与字典树
title: 字符串hash与字典树 date: 2018-08-01 22:05:29 tags: acm 算法 字符串 概述 这篇主要是关于字符串里的 字符串hash 和 字符串字典树,,两个都是 ...
- 转载:字符串hash总结(hash是一门优雅的暴力!)
转载自:远航休息栈 字符串Hash总结 Hash是什么意思呢?某度翻译告诉我们: hash 英[hæʃ] 美[hæʃ]n. 剁碎的食物; #号; 蔬菜肉丁;vt. 把…弄乱; 切碎; 反复推敲; 搞糟 ...
- hadoop Partiton中的字符串Hash函数改进
最近的MapReduce端的Partition根据map生成的Key来进行哈希,导致哈希出来的Reduce端处理任务数量非常不均匀,有些Reduce端处理的数据量非常小(几分钟就执行完成,而最后的pa ...
- 转载:字符串HASH
转载自:Slager_Z 字符串Hash总结 Hash是什么意思呢?某度翻译告诉我们: hash 英[hæʃ] 美[hæʃ]n. 剁碎的食物; #号; 蔬菜肉丁;vt. 把…弄乱; 切碎; 反复推敲; ...
- 89.hash算法实现CSDN密码处理
初始化,数据的行数,hash链表结构体,存储头结点 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdl ...
随机推荐
- STL算法设计理念 - 函数适配器
1)函数适配器的理论知识 2)常用函数函数适配器 标准库提供一组函数适配器,用来特殊化或者扩展一元和二元函数对象.常用适配器是: 1.绑定器(binder): binder通过把二元函数对象的一个实参 ...
- AngularJS进阶(十二)AngularJS常用知识汇总(不断更新中....)
AngularJS常用知识汇总(不断更新中....) 注:请点击此处进行充电! app.controller('editCtrl',['$http','$location','$rootScope', ...
- 02_Nginx基本配置与参数说明 + 辅助命令
Nginx基本配置与参数说明,下面是nginx.conf配置文件 #运行用户 #user nobody; worker_processes 2; #全局错误日志及PID文件 #error_l ...
- LeetCode之“链表”:Sort List
题目链接 题目要求: Sort a linked list in O(n log n) time using constant space complexity. 满足O(n log n)时间复杂度的 ...
- bash下如何使用bind[En]
You can determine the character sequence emitted by a key by pressing Ctrl-v at the command line, th ...
- UITabbar的一些常规用法(总结)
往往系统自带的UITabbar 不能满足我们的样式或者颜色设计,所以需要调整UITabbar. 1.自定义UITabbar,也是我学到的第一种方式(简单暴力). 先记录一下思路: 首先,隐藏系统自带的 ...
- Github搜索技巧-如何使用github找到自己感兴趣的项目
Github现在不仅仅作为一个版本控制工具,更是一个开源的仓库,里面不但有优秀的开源代码,电子书,还有一些五花八门的项目,有些国家的法律也放在上面,作为程序员如何找到自己感兴趣的项目就非常重要了! 欢 ...
- 高仿qq健康
概述 学习别人的代码,在此基础上 优化代码结构 增加动画 要点记录 通过mRatio参数,让宽高始终是一个比例 贝塞尔曲线手动画矩形圆角 画虚线 根据基准点绘制文字 属性动画的使用 画笔宽度的自适应 ...
- 和菜鸟一起学linux之upnp协议的学习记录
UPnP全名是Universal Plug and Play,主要是微软在推行的一个标准.简单的来说,UPnP 最大的愿景就是希望任何设备只要一接上网络,所有在网络上的设备马上就能知道有新设备加入,这 ...
- java中文拼音字母排序
package com.yputil.util; import java.text.CollationKey;import java.text.Collator;import java.util.Ar ...