一些 hash function 基本知识个人总结

510 阅读2分钟

总结了一些hash function相关的知识,供技术选型时用。

如何评价一个hash function?

  1. 性能。 生成N个M长度的hash值需要的时间和资源。注意:

    1. 不同处理器、不同语言上结果不同
    2. 不同函数擅长的长度也不同
    3. 不同的数据类型(数字,字符,UTF..)的性能结果也不同
  2. 碰撞性。使用函数:image-20221129005738-km9j7xl.png

    生成n个hash值放在有m个slot的链表里。bj表示第j个slot上的hash值的数量。 分子表示程序为了从链表里找到某一个值的期望查找次数 ;分母表示把一个hash值放在合适的位置需要的查询次数。 理想状态下结果在1左右 [0.95, 1.05]。如果结果比较大,表示碰撞率比较高;如果结果比1还小,说明这个函数的碰撞性比纯随机还好。

  3. 稳定性。即对同样的key,能否一直生成同一个hash。各种程序语言的内置bash table实现里的hash function往往就不能确保这一点,每个进程生成的都不同。

一些常见的hash function

md5 /sha1

最常用。一般用来作为信息摘要使用, 信息不可逆。如果仅仅是用来生成key值,性能比较差。

fnv/murmur

都是生成一个uint64或uint32,可以对这个数字再自行进行base或者hex操作。性能高,都适合作为key值。

两者在性能上也很接近,不同场景、语言下互有胜负。但fnv是个更安全的选择。

cityhash&farmhash

谷歌的产品,借鉴了murmur的设计,性能比它高得多。可以作为前两者的上位替代。

其中farmhash是前者的升级版

xxhash

近几年出现的性能极高的hash:Cyan4973/xxHash: Extremely fast non-cryptographic hash algorithm (github.com), 性能比上面这些都高得多。

wyhash

又一个近几年出现的,性能更高的hash: wangyi-fudan/wyhash: The FASTEST QUALITY hash function, random number generators (PRNG) and hash map. (github.com)

根据多个不同的benchmark, 可能是目前最快的。golang标准库里已经在使用了。

关于性能

其实并非性能高就一定是好的,有些场景下反而需要性能差的,比如密码加密需要增加被暴力破解的成本。