djb2:一个产生简单的随机分布的哈希函数
LCG算法
djb2与LCG很类似,故先介绍 LCG。
LCG(linear congruential generator)算法是一个古老的产生随机数的算法。由以下参数产生
| 参数 | m | a | c | X |
|---|---|---|---|---|
| 性质 | 模数 | 乘数 | 加数 | 随机数 |
| 作用 | 取模 | 移位 | 偏移 | 作为结果 |
LCG算法是如下的一个递推公式,每下一个随机数是当前随机数向左移动 log2 a 位,加上一个 c,最后对 m 取余,使随机数限制在 0 ~ m-1 内

从该式可以看出,该算法由于构成简单,具有以下优点:
- 计算速度快
- 易于实现
- 易于写入硬件
以下是针对不同参数 lcg 产生随机数的效果图

可以看出,针对不同的参数,lcg产生的效果差别很大
以下是针对不同环境下的参数选择

示例代码
def lcg(modulus, a, c, seed):
while True:
seed = (a * seed + c) % modulus
yield seed
djb2
djb2是一个产生随机分布的的哈希函数,与LCG的算法相似。
以下是 djb2 的哈希函数:
X = (a * X) + c; // "mod M", M = 2^32 或 2^64
示例代码
// generates a hash value for a sting
// same as djb2 hash function
//构造哈希函数 f(hash)= hash * 33 + c
unsigned int CountMinSketch::hashstr(const char *str) {
unsigned long hash = 5381;
int c;
while (c = *str++) {
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
}
return hash;
}
本部分利用djb2处理字符串。
其中参数常有以下取值:
M=2^32
M常取一个较大的质数,以减少冲突。
由于哈希函数构造简单,使用移位和相加的操作,所以计算速度快。
要注意hash值的计算,在不同机器上,可能会造成溢出的问题,可以及时对hash值取余。但是会增加计算开销,造成hash范围减小的问题。
为什么选择参数33和
33 was chosen because:
乘法易于移位或相加
从移位和加法实现中可以看到,使用33可以复制散列累加器中的大多数输入位,然后将这些位相对地分散开来。这有助于形成好的雪崩现象。使用较大的移位将复制更少的位,使用较小的移位将使位交互更局部,并使交互扩展所需的时间更长。
32 = 2^5,32 与移 5 位相关,有助于将每一个字符串的每一位比特都作用到最终的哈希值当中
在考虑ASCII字符数据时,5的移位是一个很好的移位量。ASCII字符可以看作是4位字符类型选择器和4位字符类型选择器。前4位的数字都是0x3。因此,8位移位将导致具有特定含义的位与具有相同含义的其他位相互作用。4位或2位的移位同样会在相似的位之间产生强烈的交互作用。5位的移位使得一个字符的4个低阶位中的许多位与同一字符的4个上位中的许多强相互作用。
5381 was chosen because
- 选择5381并不太重要,很多其他的大的质数数也可以运行地很好。
哈希选择参考
源自 https://stackoverflow.com/questions/1579721/why-are-5381-and-33-so-important-in-the-djb2-algorithm
djb2不是一个快速哈希函数,因为它每次处理输入一个字符,并且不尝试使用指令级并行。
在现代处理器,乘法时该算法要快得多了乘法和其他因素(如2 ^ 13 + 2 ^ 5 + 1)可能也有类似的表现,有更好的输出,更容易写。
一个好的非加密哈希函数不希望产生随机输出。相反,给定两个几乎完全相同的输入,它希望产生完全不同的输出。
如果你的输入值是随机分布的,你不需要一个好的哈希函数,你可以使用你输入的任意一组比特。一些现代哈希函数(Jenkins 3, Murmur, probably CityHash)产生的输出分布比高度相似的随机输入更好。
选择哈希函数的详细博客 https://blog.csdn.net/xu20082100226/article/details/52651212
djb2:一个产生简单的随机分布的哈希函数的更多相关文章
- .Net Excel 导出图表Demo(柱状图,多标签页) .net工具类 分享一个简单的随机分红包的实现方式
.Net Excel 导出图表Demo(柱状图,多标签页) 1 使用插件名称Epplus,多个Sheet页数据应用,Demo为柱状图(Epplus支持多种图表) 2 Epplus 的安装和引用 新建一 ...
- QBuffer简单操作(被看做一个标准的可随机访问的文件,支持信号)
Qt中通过QBuffer类我们可以使用io的方式访问.操作QByteArray中的内容.此时,QByteArray被看做一个标准的可随机访问的文件.例如: QBuffer buffer; char c ...
- 分布式存储数据库的Key的随机分布(RP)和顺序分布(OPP)
在分布式存储数据库的世界中,无论是基于Key/Value的数据库还是Column Base(比如HBase)的数据库,都有一个重要的因子------Key,或者叫RowKey.我们总是根据Key来快速 ...
- SAS文档:简单的随机点名器
本次实验,我们设计了一个简单的随机点名系统,下面我来介绍一下它的SRS文档. 1.功能需求: 1.1 模块1 在此模块中,我们设置了RandomName类,创建一个随机点名器,里面加入了所在课程的名单 ...
- 实现一个最简单的plot函数调用:
实现一个最简单的plot函数调用: 1 import matplotlib.pyplot as plt 2 3 y=pp.DS.Transac_open # 设置y轴数据,以数组形式提供 4 5 x= ...
- Python使用multiprocessing实现一个最简单的分布式作业调度系统
Python使用multiprocessing实现一个最简单的分布式作业调度系统介绍Python的multiprocessing模块不但支持多进程,其中managers子模块还支持把多进程分布到多台机 ...
- [.NET] 打造一个很简单的文档转换器 - 使用组件 Spire.Office
打造一个很简单的文档转换器 - 使用组件 Spire.Office [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6024827.html 序 之前,& ...
- IoC原理-使用反射/Emit来实现一个最简单的IoC容器
从Unity到Spring.Net,到Ninject,几年来陆陆续续用过几个IoC框架.虽然会用,但也没有一直仔细的研究过IoC实现的过程.最近花了点时间,下了Ninject的源码,研究了一番,颇有收 ...
- 【最简单IOC容器实现】实现一个最简单的IOC容器
前面DebugLZQ的两篇博文: 浅谈IOC--说清楚IOC是什么 IoC Container Benchmark - Performance comparison 在浅谈IOC--说清楚IOC是什么 ...
随机推荐
- C++11:实用特性
今天逛cplusplus.com发现C++还真多了不少方便使用的特性,先了解些最常用的 初始化列表 vector<,,,}); vector<pair<int, int> &g ...
- Java 学习笔记(2)——基本语句、控制结构
上一篇中简单谈了一下自己对Java的一些看法并起了一个头,现在继续总结java的相关语法.java语法总体上与C/C++一样,所以对于一个C/C++程序员来说,天生就能看懂Java代码.在学习java ...
- java三元运算符
由?:符号表示的,具体的含义其实就和if-else结构的含义差不多,这种运算符会将某个条件作两种处理,如果满足条件的话就执行第一个结果,如果不满足的话就执行另外一个结果,例如: Int A,B,C; ...
- C#代码处理网页关于登录的code
作者:血饮狂龙链接:https://www.zhihu.com/question/49452639/answer/117294801来源:知乎著作权归作者所有,转载请联系作者获得授权. private ...
- PHP进阶知识总结
周末梳理了下这段时间看书的一些知识点,进步的过程不仅要实践,还要安排多看书.思考.总结. 只针对知识点进行了罗列和简单说明,很多细节还未整理好,待后面再专门详细写. 基础易忽略概念 PHP是一个支持面 ...
- Bootstrap 在线引用
Bootstrap 3.3.0 js 文件 <script src="http://cdn.bootcss.com/bootstrap/3.3.0/js/bootstrap.min.j ...
- robbe-1.2发布-支持最新版本的friso+WinNT下php各版本的dll
robbe是建立在friso中文分词组建上的一个高性能php中文分词扩展.(只支持UTF-8编码) robbe-1.2: 1. friso近几天发布1.3了, 接口有些许变化, 更改robbe适合最新 ...
- 把KB转化为KB及以上单位
/** * 把KB转化为KB及以上单位 * @param int $kb * @return string $new_val */ function return_over_kb($kb) { $kb ...
- 用canvas播放scratch文件
原文地址:https://blog.csdn.net/qq_36268036/article/details/84262540 基于Github上的scratch-render实现sb2或者sb3文件 ...
- matplotlib点线 坐标刻度 3D图绘制(六)
plot语句中支持除X,Y以外的参数,以字符串形式存在,来控制颜色.线型.点型等要素,语法形式为: plt.plot(X, Y, 'format', ...) 1 点和线的样式 颜色 参数color或 ...