常用哈希函数的比较及其C语言实现

来源:互联网 发布:炒股软件免费下载 编辑:程序博客网 时间:2024/06/05 17:07
基本概念
所谓完美哈希函数,就是指没有冲突的哈希函数,即对任意的 key1 != key2 有h(key1) != h(key2)。
设定义域为X,值域为Y, n=|X|,m=|Y|,那么肯定有m>=n,如果对于不同的key1,key2属于X,有h(key1)!=h(key2),那么称h为完美哈希函数,当m=n时,h称为最小完美哈希函数(这个时候就是一一映射了)。

在处理大规模字符串数据时,经常要为每个字符串分配一个整数ID。这就需要一个字符串的哈希函数。怎么样找到一个完美的字符串hash函数呢?

有一些常用的字符串hash函数。像BKDRHash,APHash,DJBHash,JSHash,RSHash,SDBMHash,PJWHash,ELFHash等等。都是比较经典的。

常用的字符串Hash函数还有ELFHash,APHash等等,都是十分简单有效的方法。这些函数使用位运算使得每一个字符都对最后的函数值产生影响。另外还有以MD5和SHA1为代表的杂凑函数,这些函数几乎不可能找到碰撞。

常用字符串哈希函数有 BKDRHash,APHash,DJBHash,JSHash,RSHash,SDBMHash,PJWHash,ELFHash等等。对于以上几种哈希函数,我对其进行了一个小小的评测。

Hash函数数据1数据2数据3数据4数据1得分数据2得分数据3得分数据4得分平均分BKDRHash20477448196.5510090.9582.0592.64APHash23475449396.5588.4610051.2886.28DJBHash22497547496.5592.31010083.43JSHash14476150610084.6296.8317.9581.94RSHash10486150510010051.5820.5175.96SDBMHash32484950493.192.3157.0123.0872.41PJWHash302648785130043.89021.95ELFHash302648785130043.89021.95
其中数据1为100000个字母和数字组成的随机串哈希冲突个数。数据2为100000个有意义的英文句子哈希冲突个数。数据3为数据1的哈希值与 1000003(大素数)求模后存储到线性表中冲突的个数。数据4为数据1的哈希值与10000019(更大素数)求模后存储到线性表中冲突的个数。


经过比较,得出以上平均得分。平均数为平方平均数。可以发现,BKDRHash无论是在实际效果还是编码实现中,效果都是最突出的。APHash也是较为优秀的算法。DJBHash,JSHash,RSHash与SDBMHash各有千秋。PJWHash与ELFHash效果最差,但得分相似,其算法本质是相似的。

unsigned int SDBMHash(char *str){    unsigned int hash = 0;     while (*str)    {        // equivalent to: hash = 65599*hash + (*str++);        hash = (*str++) + (hash << 6) + (hash << 16) - hash;    }     return (hash & 0x7FFFFFFF);} // RS Hash Functionunsigned int RSHash(char *str){    unsigned int b = 378551;    unsigned int a = 63689;    unsigned int hash = 0;     while (*str)    {        hash = hash * a + (*str++);        a *= b;    }     return (hash & 0x7FFFFFFF);} // JS Hash Functionunsigned int JSHash(char *str){    unsigned int hash = 1315423911;     while (*str)    {        hash ^= ((hash << 5) + (*str++) + (hash >> 2));    }     return (hash & 0x7FFFFFFF);} // P. J. Weinberger Hash Functionunsigned int PJWHash(char *str){    unsigned int BitsInUnignedInt = (unsigned int)(sizeof(unsigned int) * 8);    unsigned int ThreeQuarters    = (unsigned int)((BitsInUnignedInt  * 3) / 4);    unsigned int OneEighth        = (unsigned int)(BitsInUnignedInt / 8);    unsigned int HighBits         = (unsigned int)(0xFFFFFFFF) << (BitsInUnignedInt - OneEighth);    unsigned int hash             = 0;    unsigned int test             = 0;     while (*str)    {        hash = (hash << OneEighth) + (*str++);        if ((test = hash & HighBits) != 0)        {            hash = ((hash ^ (test >> ThreeQuarters)) & (~HighBits));        }    }     return (hash & 0x7FFFFFFF);} // ELF Hash Functionunsigned int ELFHash(char *str){    unsigned int hash = 0;    unsigned int x    = 0;     while (*str)    {        hash = (hash << 4) + (*str++);        if ((x = hash & 0xF0000000L) != 0)        {            hash ^= (x >> 24);            hash &= ~x;        }    }     return (hash & 0x7FFFFFFF);} // BKDR Hash Functionunsigned int BKDRHash(char *str){    unsigned int seed = 131; // 31 131 1313 13131 131313 etc..    unsigned int hash = 0;     while (*str)    {        hash = hash * seed + (*str++);    }     return (hash & 0x7FFFFFFF);} // DJB Hash Functionunsigned int DJBHash(char *str){    unsigned int hash = 5381;     while (*str)    {        hash += (hash << 5) + (*str++);    }     return (hash & 0x7FFFFFFF);} // AP Hash Functionunsigned int APHash(char *str){    unsigned int hash = 0;    int i;     for (i=0; *str; i++)    {        if ((i & 1) == 0)        {            hash ^= ((hash << 7) ^ (*str++) ^ (hash >> 3));        }        else        {            hash ^= (~((hash << 11) ^ (*str++) ^ (hash >> 5)));        }    }     return (hash & 0x7FFFFFFF);}

编程珠玑中的一个hash函数

//用跟元素个数最接近的质数作为散列表的大小#define NHASH 29989#define MULT 31unsigned in hash(char *p){    unsigned int h = 0;    for (; *p; p++)        h = MULT *h + *p;    return h % NHASH;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 清算组出的报告书无法清算怎么办 手机停机了收不到快递取件码怎么办 买东西货到了不小心确认收货怎么办 不小心用了蚂蚁花呗怎么办 q微店忘记密码怎么办微忘记密 在优酷买了开通会员不想续费怎么办 微店怎么卖吃的要认证怎么办 在天猫买东西遇到不讲理卖家怎么办 天猫退货收到退款了卖家拒绝怎么办 申请退款保证金不够的情况下怎么办 发奖品把钱骗走了应该怎么办? 淘宝东西没到自动确认了收货怎么办 淘宝买的东西收不到货怎么办 资料如实填了 怎么办不下来借款啊 如果淘宝店家跑了没收到货怎么办 淘宝店家退完款把货又发了怎么办 淘宝收到货有问题客服不回复怎么办 手机从美国寄回中国被海关扣怎么办 摩托车新买的后悔了想卖怎么办? 淘宝单号输错了怎么办运费险 在淘宝卖东西快递单号输错了怎么办 淘宝买东西签收后发现坏了怎么办 摩托车购车发票写了别人名字怎么办 新领的发票跟电脑对不上号怎么办 淘宝未发货退款卖家拒绝怎么办 在超市买东西把票丢了不让出怎么办 在淘宝上买东西付款不发货怎么办 买家拍下商品卖家拒绝发货怎么办 没有中文标签被投诉到工商局怎么办 淘宝申请退款卖家强制发货怎么办 1688卖家交易不小心关闭怎么办 拼多多两天不发货怎么办自动退款吗 在家里放的东西找不到了怎么办 在家里烧东西烟太大了怎么办 转转上买的二手东西有问题怎么办? 大巴车过虎门大桥错走小车道怎么办 pe高压膜中间松两边紧怎么办? 穿着浅口的高跟鞋走路老是掉怎么办 五吧同城模特兼职被骗了怎么办 华为手机充电玩黑屏怎么办教学视频 衣服肩膀被衣架撑变形了怎么办