Cuckoo Hash
最近在看APSI中,涉及到了一些hash技术(朴素hash,置换hash,布谷鸟hash),Hash 技术是 PSI 协议中优化通信复杂度和计算杂度的重要工具之一,现在系统的认识一下!
更多关于哈希函数的参考:哈希函数
朴素hash(plain hash)
使用\(ℎℎ_(·)\)将元素映射到具有 b 个桶的 Hash 表 T 中的 \(k\)个位置, 每个桶最多有\(lb(n)\)个元素(\(n\)为集合的元素个数),其中\(ℎℎ_(·)\)表示\(k\)个不同的Hash 函数 \(h_1(·), h_2(·),...,h_k(·)\).
比如:
该表中有四个桶,每个桶中最多可以存4个值。

置换hash(permutation-based hash)
将元素转化为更短的字符串并存储在 Hash 表中, 以此减少存储空间和计算复杂度.
元素插入如下: 元素 \(x\) 表示为bit 的形式并拆分为 2 部分 \(x_1, x_2\). 为元素获取 Hash表的索引: \(_1 ⊕ (_2)\), \(H\) 为 Hash 函数.
最后桶中存储大小为\(|_2| = || − |_1|\),其中\(|x|\)表示 \(x\) 的比特长度;\(⊕\)表示按位异或.
布谷鸟hash(cuckoo hash)
思考一个问题:为什么要用布谷鸟哈希?
1、首先是能隐藏数据
2、是一个高性能的哈希方案
3、哈希的本质是从一个较大空间映射到一个较小的空间,因此在插入数据足够多之后,根据鸽巢原理,一定会存在位置冲突。常见的哈希表(Hash Table 或者字典,dictionary)会通过链表、开放地址探测等方式来处理冲突。单桶多函数的布谷鸟哈希,便是开放地址法处理冲突的一种哈希表,只不过有冲突后,不是通过线性寻找新的位置,而是通过额外哈希函数来寻找。
背景
Cuckoo中文名叫布谷鸟,这种鸟有一种即狡猾又贪婪的习性,它不肯自己筑巢, 而是把蛋下到别的鸟巢里,而且它的幼鸟又会比别的鸟早出生,布谷幼鸟天生有一种残忍的动作,幼鸟会拼命把未出生的其它鸟蛋挤出窝巢,今后以便独享“养父 母”的食物。借助生物学上这一典故,cuckoo hashing处理碰撞的方法,就是把原来占用位置的这个元素踢走,不过被踢出去的元素还要比鸟蛋幸运,因为它还有一个备用位置可以安置,如果备用位置上 还有人,再把它踢走,如此往复。直到被踢的次数达到一个上限,才确认哈希表已满,并执行rehash操作。
定义
布谷鸟哈希最早是 Rasmus Pagh 和 Flemming Friche Rodler 在 2001 年一次会议上公开的 。
思想
使用\(ℎℎ_(·)\)将元素 \(e\) 映射到具有 \(b\) 个桶的 Hash 表 T 中的某一个位置, 确保每个桶只能有 1 个元素:
- 计算 \(h_1(e), h_2(e), ..., h_k(e)\), 如果 \(T[h_1(e)], T[h_2(e)], …, T[h_k(e)]\)至少有 1 个桶为空, 则随机插入;如果都不为空, 则随机选择\(T[h_i(e)]\), 替换桶中的元素 \(T[h_i(e’)]\), 再对被替换元素\(e’\)执行上述操作.
当上述替换操作达到一定阈值时, 则将 \(e’\)放置在额外的存储空间 stash 中. 因此, 元素 \(e\)必定在以下容器中找到: \(T[h_1(e)], T[h_2(e)], …, T[h_k(e)]\)或 \(stash\). 由于 \(stash\) 可能会存在溢出威胁而导致Hash 错误, Pinkas 等人[5]通过实验分析出 Hash 函数个数、\(stash\) 大小和桶数 \(b\) 的最佳关系.
变种
布谷鸟哈希可以有很多变种
使用两个哈希函数和一个哈希桶(表只有一个桶)
- 对key值hash,生成两个hash key值,hashk1和 hashk2, 如果对应的两个位置上有一个为空,那么直接把key插入即可。
- 否则,任选一个位置,把key值插入,把已经在那个位置的key值踢出来。
- 被踢出来的key值,需要选择另外一个hash函数插入,直到没有key被踢出为止。
下面是第一种情况,有空位置,直接插入即可!

下面是出现碰撞的情况,需要被踢出,选择另外一个hash函数重新插入

举例
假设有两个hash函数:

下面依次插入item:

可以看作两张表,但序号是一致的。
当再次插入item:6时,就出现了问题,插入失败:

应用
cmu 大学的 Bin Fan 等人,在 2014 年发表了一篇名为:Cuckoo Filter: Practically Better Than Bloom的论文,基本思想是将布谷鸟哈希(cuckoo hash)的思想应用于集合(set membership)方向,可以替代工程中常用的 Bloom Filter(布隆过滤器),有以下优势:
1、支持删除元素
2、更高的查询效率,尤其在高负载因子时
3、相比其他支持删除的 Filter 更容易实现
4、如果期望误报率在 3% 以下,所用空间比 Bloom Filter 少
为了达到以上效果,Cuckoo Filter 对原 Cuckoo Hash 做了如下改变:
1、为了提高桶的利用率,使用多路哈希桶。
2、为了减少内存的使用,只存储 key 指纹(不懂就问,什么是key指纹?)。
实现
微软有一个开源库:Kuku,下面说一下怎么用。
介绍
Kuku是一个简单的开源(MIT许可)布谷鸟哈希库,由微软的加密和隐私研究小组开发。KuCu是用现代标准C++编写的,没有外部依赖关系,便于在许多不同的环境中编译和运行。
cuckoo hash
布谷鸟哈希是一种哈希技术,可以实现非常高的填充率,尤其能创建高效的哈希表,每个桶(bin)中只有一个项目。这是通过使用多个(通常是2、3或4个)不同的哈希函数实现的,如下所示:
(1)\(H_1, H_2, ..., H_k\)表示hash函数
(2)当\(X\)要插入时,任意选择一个hash函数\(H_j\),判断对应的bin是否为空(\(H_j(X)\)所对应的位置),如果为空,则插入\(X\),返回\(True\);否则,移除bin中存在的值\(Y\),将\(X\)插入到该位置,\(Y\)则重新执行插入操作(选用其他的hash函数)
(3)如果尝试多次后失败,则将item放入预准备好的最大容量的桶(stash)中,然后返回\(True\)
(4)如果stash已经达到装满,将该item储存在"已知位置"并返回\(False\)
不太理解这个已知位置;stash可以看作是另外一张hash表
为了判断一个item:\(Z\)是否在hash表中,需要逐个比较\(H_1(Z), H_2(Z), ..., H_k(Z)\),stash同样也是。如果不需要使用stash,则使长度为0即可。
kuku
Kuku是一个简约的库,它支持布谷鸟哈希的某些变体,如上所述。它使用Tabulation hashing作为hash函数。Kuku中的item的长度正好是128位,不能增加;然而较长的item总是可以使用其他一些接受任意输入长度的哈希函数哈希到128位,并且输出可以随后在Kuku中使用。
Tabulation hashing:一种特殊的hash函数
安装

//下载库
git clone https://github.com/Microsoft/Kuku
//编译,这样生成的静态文件/build/lib/libkuku-2.1.a,但没有编译example和test下文件
cd kuku-main
cmake -S . -B build
cmake --build build
//编译(exapme和test)
cmake -S . -B build -DKUKU_BUILD_EXAMPLES=ON
cmake -S . -B build -DKUKU_BUILD_TESTS=ON
cmake --build build
最后结果在/build/bin下:

使用
example实例
主要模块
主要是src/kuku下的文件
(1)locfunc
(2)kuku
(3)common
参考
1、Cuckoo Hash 布谷鸟哈希
2、布谷鸟哈希和布谷鸟过滤器
3、CUCKOO FILTER:设计与实现
4、面向隐私保护的集合交集计算综述
5、Scalable private set intersection based on OT extension
Cuckoo Hash的更多相关文章
- Cuckoo hash算法分析
一 基本思想: cuckoo hash是一种解决hash冲突的方法,其目的是使用简单的hash 函数来提高hash table的利用率,同时保证O(1)的查询时间 基本思想是使用2个hash函数来处理 ...
- Cuckoo Hash和多级Hash的粗浅认识
通过对Cuckoo Hash.多级Hash和BloomFilter的粗浅了解,感觉它们三者存在类似之处,算是近亲(暂且把普通的Hash称作远亲). Cuckoo Hash的思想非常简单,冲突时,重Ha ...
- Cuckoo Hash——Hash冲突的解决办法
参考文献: 1.Cuckoo Filter hash算法 2.cuckoo hash 用途: Cuckoo Hash(布谷鸟散列).问了解决哈希冲突的问题而提出,利用较少的计算换取较大的空间.占用空间 ...
- Cuckoo hash算法分析——其根本思想和bloom filter一致 增加hash函数来解决碰撞 节省了空间但代价是查找次数增加
基本思想: cuckoo hash是一种解决hash冲突的方法,其目的是使用简单的hash 函数来提高hash table的利用率,同时保证O(1)的查询时间 基本思想是使用2个hash函数来处理碰撞 ...
- 过滤器系列(二)—— Cuckoo filter
这一篇讲的是布谷过滤器(cuckoo fliter),这个名字来源于更早发表的布谷散列(cuckoo hash),尽管我也不知道为什么当初要给这种散列表起个鸟名=_= 由于布谷过滤器本身的思想就源自于 ...
- DPDK L3fwd 源码阅读
代码部分 整个L3fwd有三千多行代码,但总体思想就是在L2fwd的基础上,增加网络层的根据 IP 地址进行路由查找的内容. main.c 文件 int main(int argc, char **a ...
- 阅读 CloudDPI:Cloud+DPI+Reversible Sketch
CloudDPI: Cloud-Based Privacy-Preserving Deep Packet Inspection via Reversible Sketch 与sketch的结合点:将修 ...
- [GitHub] 75+的 C# 数据结构和算法实现
C#中标准数据结构和算法的即插即用类库项目 GitHub:https://github.com/aalhour/C-Sharp-Algorithms Watch: 307 Star: 3.4k For ...
- Cuckoo for Hashing(hash)hunnuoj
Problem B:Cuckoo for HashingAn integer hash table is a data structure that supports insert, delete a ...
- BloomFilter 与 Cuckoo Filter
BloomFilter 与 CuckooFilter Bloom Filter 原理 Bloom Filter是一种空间效率很高的随机数据结构,它的原理是,当一个元素被加入集合时,通过K个相互独立的H ...
随机推荐
- 货店管理(delphi+sqlserver)
之前给朋友做的货店管理程序,个人使用,数据量小,delphi开发的,sqlserver express版,fastReport做的报表(报表可以修改). 源代码全给他的,呵呵,他也可以简单修改了. ...
- ExtJS & Asp.NET
企业应用中,要快速开发Web应用,前端使用ExtJS还行,包含许多常用的控件,图标,配色方案... 帖上部分载图: 完全可订制的登录界面: 可调整的布局: 可综合使用的模态对话框: 树结构及动态加载: ...
- typescript 安装调试(二)
一.安装ts-node 今天介绍另外一种更加方便的ts调试方式,需要安装以下几个库 第一个库是ts-node,这个库可以直接运行ts文件无需实时编译成js文件后再运行 安装命令 npm i ts-n ...
- ThreeJs-02Threejs开发入门与调试
这两天没有上传笔记,在解决图床的问题,主打一个白嫖,所以要费点心思,先是用了gitee的图床好不容易配好后发现居然加了防盗链,后面又转了github的咱目前来说github也是最稳定且免费的,现在搞好 ...
- (Redis基础教程之九) 如何在Redis中使用Sorted Sets
介绍 Redis是一个开源的内存中键值数据存储.在Redis的,排序集合类似于一个数据类型集在这两者都是串的非重复的组.不同之处在于,已排序集中的每个成员都与一个分数相关联,从而可以从最小分数到最大分 ...
- 啃啃老菜:Spring IOC核心源码学习(一)
啃啃老菜:Spring IOC核心源码学习(一) 本文主要以spring ioc容器基本代码骨架为切入点,理解ioc容器的基本代码组件结构,各代码组件细节剖析将放在后面的学习文章里. 关于IOC容器 ...
- Java 并发编程实战学习笔记——串行任务转并行任务
package net.jcip.examples; import java.util.Collection; import java.util.List; import java.util.Queu ...
- Python模块之functools.partial
在Python编程中,functools.partial是一个强大的工具,它提供了一种部分应用函数的方式,能够在创建新函数时固定部分参数,从而在后续调用中减少需要传递的参数数量.本文将深入介绍func ...
- 移动端自动化之Autox.js
github: https://github.com/kkevsekk1/AutoX 官方文档:http://doc.autoxjs.com/ 1. 安装vscode的扩展插件 如果之前有使用 aut ...
- golang之媒体处理
[视频] 获取视频封面图: 1) 如果是使用oss的话, 可以添加指定的后缀生成指定图片 视频截帧: https://help.aliyun.com/zh/oss/user-guide/video-s ...