Hash 的核心思想在于,将输入映射到一个值域较小、可以方便比较的范围,典型的用法就是将资源紧张的设备中的不定长字符串转化为定长整数,以达到节省空间的目的

如:printf("This is a string.")  =>  printf("0x12345678")   // 理想哈希算法可将不同的字符串转化为唯一的整数

常用hash算法:

  • 00 - RS 哈希函数
unsigned int RSHash(const char* str, unsigned int length)
{
unsigned int b = 378551;
unsigned int a = 63689;
unsigned int hash = 0;
unsigned int i = 0; for (i = 0; i < length; ++str, ++i)
{
hash = hash * a + (*str);
a = a * b;
} return hash;
}
  • 01 - JS 哈希函数
unsigned int JSHash(const char* str, unsigned int length)
{
unsigned int hash = 1315423911;
unsigned int i = 0; for (i = 0; i < length; ++str, ++i)
{
hash ^= ((hash << 5) + (*str) + (hash >> 2));
} return hash;
}
  • 02 - PJW 哈希函数
unsigned int PJWHash(const char* str, unsigned int length)
{
const unsigned int BitsInUnsignedInt = (unsigned int)(sizeof(unsigned int) * 8);
const unsigned int ThreeQuarters = (unsigned int)((BitsInUnsignedInt * 3) / 4);
const unsigned int OneEighth = (unsigned int)(BitsInUnsignedInt / 8);
const unsigned int HighBits = (unsigned int)(0xFFFFFFFF) << (BitsInUnsignedInt - OneEighth);
unsigned int hash = 0;
unsigned int test = 0;
unsigned int i = 0; for (i = 0; i < length; ++str, ++i)
{
hash = (hash << OneEighth) + (*str); if ((test = hash & HighBits) != 0)
{
hash = (( hash ^ (test >> ThreeQuarters)) & (~HighBits));
}
} return hash;
}
  • 03 - ELF哈希函数
unsigned int ELFHash(const char* str, unsigned int length)
{
unsigned int hash = 0;
unsigned int x = 0;
unsigned int i = 0; for (i = 0; i < length; ++str, ++i)
{
hash = (hash << 4) + (*str); if ((x = hash & 0xF0000000L) != 0)
{
hash ^= (x >> 24);
} hash &= ~x;
} return hash;
}
  • 04 - BKDR 哈希函数
unsigned int BKDRHash(const char* str, unsigned int length)
{
unsigned int seed = 131; /* 31 131 1313 13131 131313 etc.. */
unsigned int hash = 0;
unsigned int i = 0; for (i = 0; i < length; ++str, ++i)
{
hash = (hash * seed) + (*str);
} return hash;
}
  • 05 - SDBM哈希函数
unsigned int SDBMHash(const char* str, unsigned int length)
{
unsigned int hash = 0;
unsigned int i = 0; for (i = 0; i < length; ++str, ++i)
{
hash = (*str) + (hash << 6) + (hash << 16) - hash;
} return hash;
}
  • 06 - DJB哈希函数
unsigned int DJBHash(const char* str, unsigned int length)
{
unsigned int hash = 5381;
unsigned int i = 0; for (i = 0; i < length; ++str, ++i)
{
hash = ((hash << 5) + hash) + (*str);
} return hash;
}
  • 07 - DEK哈希函数
unsigned int DEKHash(const char* str, unsigned int length)
{
unsigned int hash = len;
unsigned int i = 0; for (i = 0; i < length; ++str, ++i)
{
hash = ((hash << 5) ^ (hash >> 27)) ^ (*str);
} return hash;
}
  • 08 - AP 哈希函数
unsigned int APHash(const char* str, unsigned int length)
{
unsigned int hash = 0xAAAAAAAA;
unsigned int i = 0; for (i = 0; i < length; ++str, ++i)
{
hash ^= ((i & 1) == 0) ? ( (hash << 7) ^ (*str) * (hash >> 3)) :
(~((hash << 11) + ((*str) ^ (hash >> 5))));
} return hash;
}

各hash算法冲突率测评

Hash函数 数据1 数据2 数据3 数据4 数据1得分 数据2得分 数据3得分 数据4得分 平均分
BKDRHash 2 0 4774 481 96.55 100 90.95 82.05 92.64
APHash 2 3 4754 493 96.55 88.46 100 51.28 86.28
DJBHash 2 2 4975 474 96.55 92.31 0 100 83.43
JSHash 1 4 4761 506 100 84.62 96.83 17.95 81.94
RSHash 1 0 4861 505 100 100 51.58 20.51 75.96
SDBMHash 3 2 4849 504 93.1 92.31 57.01 23.08 72.41
PJWHash 30 26 4878 513 0 0 43.89 0 21.95
ELFHash 30 26 4878 513 0 0 43.89 0 21.95

数据1:为100000个字母和数字组成的随机串哈希冲突个数

数据2:为100000个有意义的英文句子哈希冲突个数

数据3:为数据1的哈希值与 1000003(大素数)求模后存储到线性表中冲突的个数

数据4:为数据1的哈希值与10000019(更大素数)求模后存储到线性表中冲突的个数。

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

PJWHash与ELFHash效果最差,但得分相似,其算法本质是相似的。

参考:

http://www.partow.net/programming/hashfunctions/

    https://www.cnblogs.com/uvsjoh/archive/2012/03/27/2420120.html

【Hash】字符串哈希的更多相关文章

  1. HASH 字符串哈希 映射转化

    哈希HASH的本质思想类似于映射.离散化. 哈希,通过给不同字符赋不同的值.并且钦定一个进制K和模数,从而实现一个字符串到一个模意义下的K进制数上. 它的主要目的是判重,用于$DFS$.$BFS$判重 ...

  2. 详解HASH(字符串哈希)

    HASH意为(散列),是OI的常用算法. 我们常用哈希的原因是,hash可以快速(一般来说是O(段长))的求出一个子段的hash值,然后就可以快速的判断两个串是否相同. 今天先讲string类的has ...

  3. 数据结构作业——hash(字符串哈希)

    Hash Description 给定长度为 n ( n<=1000000)的字符串,字符串仅由小写字母的前 m ( m<=6) 个字符组成,请你计算出共有多少长度为 k( k<=6 ...

  4. 从Hash Killer I、II、III论字符串哈希

    首先,Hash Killer I.II.III是BZOJ上面三道很经典的字符串哈希破解题.当时关于II,本人还琢磨了好久,但一直不明白为啥别人AC的代码都才0.3kb左右,直到CYG神犇说可以直接随机 ...

  5. Redis支持的数据类型及相应操作命令:String(字符串),Hash(哈希),List(列表),Set(集合)及zset(sorted set:有序集合)

    help 命令,3种形式: help 命令 形式 help @<group> 比如:help @generic.help @string.help @hash.help @list.hel ...

  6. 字符串哈希hash

    题目描述 如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字.大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串. 友情提醒:如果真的想好好练习哈希的话,请自觉,否则请右转 ...

  7. 【基本算法入门-字符串哈希(Hash)】-C++

    字符串哈希入门 说得通俗一点,字符串哈希实质上就是把每个不同的字符串转成不同的整数. 为什么会有这样的需要呢?很明显,存储一个超长的字符串和存储一个超大但是能存的下的整数,后者所占的空间会少的多,但主 ...

  8. Crazy Search POJ - 1200 (字符串哈希hash)

    Many people like to solve hard puzzles some of which may lead them to madness. One such puzzle could ...

  9. 牛客练习赛33 E tokitsukaze and Similar String (字符串哈希hash)

    链接:https://ac.nowcoder.com/acm/contest/308/E 来源:牛客网 tokitsukaze and Similar String 时间限制:C/C++ 2秒,其他语 ...

  10. luoguP3370 【模板】字符串哈希 [hash]

    题目描述 如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字.大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串. 友情提醒:如果真的想好好练习哈希的话,请自觉,否则请右转 ...

随机推荐

  1. 【分享】推荐一个非常好用的redis远程连接工具

    推荐一个非常好用的redis远程连接工具 蓝奏云地址 https://wwsi.lanzoum.com/ig7xZ0xspf0h 密码:4vnz 二维码:

  2. ElasticSearch之cat fielddata API

    命令样例如下: curl -X GET "https://localhost:9200/_cat/fielddata?v=true&pretty" --cacert $ES ...

  3. 探索 Linux Namespace:Docker 隔离的神奇背后

    在 深入理解 Docker 核心原理:Namespace.Cgroups 和 Rootfs 一文中我们分析了 Docker 是由三大核心技术实现的. 今天就一起分析 Docker 三大核心技术之一的 ...

  4. Python——第二章:基础数据类型

    下面是需要掌握的知识点: int, float, bool  (5星)str   (5星)list    (5星)tuple   (2星)set     (1星)dict    (5星)bytes   ...

  5. Shiro 的基本使用

    简介 Apache Shiro 是一个强大的.灵活的开源安全框架,可以干净地处理验证.授权.企业会话管理和加密等功能 相关特性 Apache Shiro 具有的主要特性如下图所示: 主要关注的地方在于 ...

  6. 一文带你全面了解openGemini

    本文分享自华为云社区<一文带你全面了解openGemini>,作者: 华为云社区精选. 7月19日,openGemini社区联合华为云DTT(技术公开直播课栏目)共同举办了一期主题为< ...

  7. 华为云 UCS (On-Premises):运行在您本地数据中心的CCE集群

    摘要:华为云分布式云原生UCS服务,是面向分布式云场景下的新一代云原生产品,提供UCS (Huawei Cloud).UCS (Partner Cloud).UCS (Multi-Cloud).UCS ...

  8. 实践GoF的设计模式:工厂方法模式

    摘要:工厂方法模式(Factory Method Pattern)将对象创建的逻辑封装起来,为使用者提供一个简单易用的对象创建接口,常用于不指定对象具体类型的情况下创建对象的场景. 本文分享自华为云社 ...

  9. 如何使用TCP/IP开发网络程序

    摘要:进行TCP协议网络程序的编写,关键在于ServerSocket套接字的熟练使用,TCP通信中所有的信息传输都是依托ServerSocket类的输入输出流进行的. 本文分享自华为云社区<Ja ...

  10. AI新手语音入门:认识词错率WER与字错率CER

    摘要:本文介绍了词错率WER和字错率CER的概念,引入了编辑距离的概念与计算方法,从而推导得到词错率或字错率的计算方法. 本文分享自华为云社区<新手语音入门(一):认识词错率WER与字错率CER ...