2019独角兽企业重金招聘Python工程师标准>>>

不约而同的,几乎所有的流行的hash map都采用了DJB hash function,俗称“Times33”算法。

Perl、Berkeley DB 、Apache、MFC、STL 等等。

times33的算法也很简单,就是不断的乘33。nHash = nHash*33 + *key++;

我没找到什么理论可以说明这种算法的合理性,据说只是通过测试和实践发现这个算法是比较好的。如果有哪位能够提供这方面的资料,不胜感激。

我 把times33和一些其他哈希算法做过比较,times33确实比我找到的其他哈希算法都更快。另外,有人说times33对英文字母效率比较好,处理 中文的时候效率就比较低;我对此进行了一些测试,发现times33在处理ascii和中文的时候,性能差异在千分之三以下,我认为这是正常的误差。

《打造最快的Hash表(和Blizzard的对话)》http://blog.csdn.net/zeronecpp/archive/2005/04/11/342756.aspx
这 是在别人的blog上看到的一篇文章,讲述blizzard如何改良hash表的。在上述哈希算法里面有一段 “seed2 + (seed2 << 5)” 相当于乘以33,其实可以看作是times33算法的变种。我对blizzard这种实现方法的效率存有怀疑。

上述blizzard的哈希算法的核心如下(我给cryptTable赋了最简单的值,而且把dwHashType设为了1):

inline UINT CMyMap::HashKey(LPCTSTR key) const
{
    int dwHashType = 1;
    unsigned long seed1 = 0x7FED7FED, seed2 = 0xEEEEEEEE;
    int ch;
    while(*key != 0)
    {
        ch = toupper(*key++);
       
        //seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);
        seed1 = ((dwHashType << 8) + ch) ^ (seed1 + seed2);
        seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;
    }
    return seed1;
}

我进行了一下测试,发现blizzard的哈希算法,分布不如经典的times33算法。它的分布如下:elements=10000, good=4293 bad2=1786 bad3=528 bad4=109 vbad=22
而经典times33算法的分布是:elements=10000, good=4443 bad2=1775 bad3=501 bad4=107 vbad=15
说 明:这是我测试程序的输出,测试的时候,我通过InitHashTable()把bucket个数设为了12007。输出中的elements表示哈希表 中一共存放了多少个元素,good表示“只有一个元素”的bucket个数,bad2表示“有两个元素”的bucket个数,bad3表示“有三个元素” 的bucket个数,vbad表示“有五个或者五个以上元素”的bucket个数。

经典times33算法如下:
inline UINT CMyMap::HashKey(LPCTSTR key) const
{
    UINT nHash = 0;
    while (*key)
        nHash = (nHash<<5) + nHash + *key++;
    return nHash;
}
从代码可以很明显的看出,blizzard的这个hash算法的计算工作量也要比经典的times33算法大很多。

我的理解是:这是为了让让同一个字符串,可以根据dwHashType 的不同而计算出不同的独立的hash值。为了实现这个目的,blizzard的这个hash算法在性能上已经付出了一些代价。

//
// 以上是对hash算法的比较
/
// 以下是对hash表整体结构的比较
//

另外,blizzard这个算法本质上还是把数据放在hash bucket里面,也同样是在每个hash bucket里面有一个list队列。
只不过一般的hash表,在找到hash bucket之后,就逐个的直接比较element;而blizzard的这个hash表,则是用“额外的两个hash值的比较”来代替element的直接比较。孰优孰劣要看具体的应用环境。
考虑到计算三次hash值的工作量,我觉得如果设置一个合适的hash bucket count,blizzard的做法可能还要更慢。
上 面我做的hash分布测试已经表明,当hash bucket count比elements大20%以上的时候,查找一个element的strcmp调用次数大约是 (4443*1+1175*2*1.5+501*3*2+107*4*2.5+15*5*3)/10000=1.2269次,大约是1.2次。(4443 个bucket只有一个element,因此一次strcmp就可以确认了。有1175个bucket有两个元素,平均要1.5次strcmp才能找到 它。以此类推。)
做1.2次strcmp()和做2次HashKey()相信大家都知道谁比较耗时了。

看来,这个所谓”最快的hash表“似乎有点名不副实呢?还是另有玄机我没看透?
所 谓"One-way hash"其实就是不可逆hash,主要是用来加密用的,和速度快不快没什么关系。实际上"One-way hash"为了达到不可逆的目的,通常总是要更慢一些。blizzard是我很喜欢的公司,我也是暴雪的铁杆fans,不过这次似乎有人夸暴雪夸错方向 了:)

在google上搜索“hash Algorithm”可以搜到很多有趣的东西。
http://www.partow.net/programming/hashfunctions/ 是一篇很有趣的文章。

转载于:https://my.oschina.net/u/554660/blog/156906

[转]哈希算法(Hash Algorithm)初探相关推荐

  1. 哈希算法(Hash Algorithm)初探

    不约而同的,几乎所有的流行的hash map都采用了DJB hash function,俗称"Times33"算法. Perl.Berkeley DB .Apache.MFC.ST ...

  2. 计算与数据结构篇 - 哈希算法 (Hash)

    计算与数据结构篇 - 哈希算法 (Hash) 哈希算法的定义和原理非常简单,基本上一句话就可以概括了.将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规则就是哈希算法,而通过原始数据映射之 ...

  3. 哈希算法(hash)加密解密

    一.哈希算法(hash)加密解密介绍 哈希,英文叫做 hash. 哈希函数(hash function)可以把 任意长度的数据(字节串)计算出一个为固定长度的结果数据. 我们习惯把 要计算 的数据称之 ...

  4. 密码技术--国密SM3哈希算法及Go语言应用

    SM3杂凑算法 sm3是我国国产的哈希算法,是一种密码散列函数标准,有国家密码管理局与2010年12月17日发布,该算法主要用于数字签名及验证,消息认证码生成及验证,随机数生成等,算法公开,其效率与s ...

  5. 哈希分布与一致性哈希算法—在swift中看到这个有意思的算法

    在研究swift的基本原理时,看到了这个算法,不怎么明白,找了几个帖子来学习.感谢@博客园一条辉的博客(liunx.cnblogs.com) @sparkliang 前言 在我们的日常web应用开发当 ...

  6. Java加密:常见哈希算法总结

    目录 一.概述 二.哈希碰撞 三.常见的哈希算法 四.简单应用代码实现 下面先以MD5算法对密码进行加密为例: 哈希算法的用途 扩展: 一.概述 哈希算法(Hash)又称摘要算法(Digest ),它 ...

  7. 一致性哈希算法 mysql_一致性哈希

    [TOC] 前言 伴随着系统流量的增大,出现了应用集群.在 Redis 中为了保证 Redis 的高可用也为 Redis 搭建了集群对数据进行分槽存放.在 Mysql数据库要存储的量达到一个很高的地步 ...

  8. 计算机视觉的几个经典算法 —— 最小二乘法 + RANSAC + 哈希算法(附DCT) + 图像聚类算法

    计算机视觉的几个经典算法 目录 计算机视觉的几个经典算法 1. 最小二乘法(寻找线性回归函数) 2. RANSAC(模型已知,参数未知) 2.1 RANSAC 与 最小二乘法的区别 2.2 RANSA ...

  9. 感知哈希算法(perceptual hash algorithm),

    感知哈希算法(perceptual hash algorithm),它的作用是对每张图像生成一个"指纹"(fingerprint)字符串,然后比较不同图像的指纹.结果越接近,就说明 ...

  10. 感知哈希算法(Perceptual hash algorithm)的OpenCV实现

    1.前言 目前"以图搜图"的引擎越来越多,可参考博文: http://blog.csdn.net/forthcriminson/article/details/8698175 此篇 ...

最新文章

  1. Data - 深入浅出学统计 - 下篇
  2. require用法php,php中的require到底是函数还是语法
  3. 高效5步走,高速搭建Hadoop2伪分布环境
  4. YARN体系学习笔记
  5. 微x怎么设置主题_红人堂:抖音直播预告文案怎么写?5个小技巧提高你的文案吸引力!...
  6. 结构与算法(05):二叉树与多叉树
  7. 用OFFICE 2007发送的文章
  8. js udp通信_Node.JS实战17:开发一个正向代理服务器
  9. JVisualVM的使用实录
  10. 推荐6本Java书籍,助你在Java路上更精进!
  11. matlab的gca和gcf,MATLAB 中gcf、gca 以及gco 的区别
  12. docker镜像的获取删除和查看镜像信息历史记录清理残余镜像
  13. (全)Docker安装+人脸比对算法服务(win10)
  14. java得到选择的复选框_java怎么获取复选框的值_java学习记录20200817
  15. CF-1200D White Lines(前缀和来两发么小老弟?)
  16. RSS阅读器简单介绍
  17. UI(1)---手机界面设计中12种常用布局
  18. docker学习整理
  19. 一键获取隐藏Wi-Fi SSID:利用Python和Scapy发现隐藏无线热点
  20. 分页第一页用0还是1_【一点资讯】程序员节:码动未来,用0和1改变世界 www.yidianzixun.com...

热门文章

  1. 采样频率和带宽的关系_示波器的采样率和存储深度在实际操作有什么用?
  2. 在Java中如何遍历Map对象
  3. 一次性掌握计算机中常见的六类指令
  4. 725.分隔链表(力扣leetcode) 博主可答疑该问题
  5. 华为p10点击六下android,要被口水喷到死机的华为P10 你用的怎么样
  6. 记一次mybatis-plus遇到的问题
  7. ASP.NET Core中使用Csp标头对抗Xss攻击
  8. cookie、session存储以及cookie使用环境 多数据存储批次加载渲染页面
  9. OpenGL笔记4 数据传递二
  10. Python练习-一辆购物车的寂寞都是Alex的错