php-perl哈希算法实现(times33哈希算法)


Posted in PHP onDecember 30, 2013
APR_DECLARE_NONSTD(unsigned int) apr_hashfunc_default(const char *char_key,
                                                      apr_ssize_t *klen)
{
    unsigned int hash = 0;
    const unsigned char *key = (const unsigned char *)char_key;
    const unsigned char *p;
    apr_ssize_t i;    /*
     * This is the popular `times 33' hash algorithm which is used by
     * perl and also appears in Berkeley DB. This is one of the best
     * known hash functions for strings because it is both computed
     * very fast and distributes very well.
     *
     * The originator may be Dan Bernstein but the code in Berkeley DB
     * cites Chris Torek as the source. The best citation I have found
     * is "Chris Torek, Hash function for text in C, Usenet message
     * <27038@mimsy.umd.edu> in comp.lang.c , October, 1990." in Rich
     * Salz's USENIX 1992 paper about INN which can be found at
     * .
     *
     * The magic of number 33, i.e. why it works better than many other
     * constants, prime or not, has never been adequately explained by
     * anyone. So I try an explanation: if one experimentally tests all
     * multipliers between 1 and 256 (as I did while writing a low-level
     * data structure library some time ago) one detects that even
     * numbers are not useable at all. The remaining 128 odd numbers
     * (except for the number 1) work more or less all equally well.
     * They all distribute in an acceptable way and this way fill a hash
     * table with an average percent of approx. 86%.
     *
     * If one compares the chi^2 values of the variants (see
     * Bob Jenkins ``Hashing Frequently Asked Questions'' at
     * http://burtleburtle.net/bob/hash/hashfaq.html for a description
     * of chi^2), the number 33 not even has the best value. But the
     * number 33 and a few other equally good numbers like 17, 31, 63,
     * 127 and 129 have nevertheless a great advantage to the remaining
     * numbers in the large set of possible multipliers: their multiply
     * operation can be replaced by a faster operation based on just one
     * shift plus either a single addition or subtraction operation. And
     * because a hash function has to both distribute good _and_ has to
     * be very fast to compute, those few numbers should be preferred.
     *
     *                  -- Ralf S. Engelschall 
     */
    if (*klen == APR_HASH_KEY_STRING) {
        for (p = key; *p; p++) {
            hash = hash * 33 + *p;
        }
        *klen = p - key;
    }
    else {
        for (p = key, i = *klen; i; i--, p++) {
            hash = hash * 33 + *p;
        }
    }
    return hash;
}

对函数注释部分的翻译: 这是很出名的times33哈希算法,此算法被perl语言采用并在Berkeley DB中出现.它是已知的最好的哈希算法之一,在处理以字符串为键值的哈希时,有着极快的计算效率和很好哈希分布.最早提出这个算法的是Dan Bernstein,但是源代码确实由Clris Torek在Berkeley DB出实作的.我找到的最确切的引文中这样说”Chris Torek,C语言文本哈希函数,Usenet消息<<27038@mimsy.umd.edu> in comp.lang.c ,1990年十月.”在Rich Salz于1992年在USENIX报上发表的讨论INN的文章中提到.这篇文章可以在上找到. 33这个奇妙的数字,为什么它能够比其他数值效果更好呢?无论重要与否,却从来没有人能够充分说明其中的原因.因此在这里,我来试着解释一下.如果某人试着测试1到256之间的每个数字(就像我前段时间写的一个底层数据结构库那样),他会发现,没有哪一个数字的表现是特别突出的.其中的128个奇数(1除外)的表现都差不多,都能够达到一个能接受的哈希分布,平均分布率大概是86%. 如果比较这128个奇数中的方差值(gibbon:统计术语,表示随机变量与它的数学期望之间的平均偏离程度)的话(见Bob Jenkins的<哈希常见疑问>http://burtleburtle.net/bob/hash/hashfaq.html,中对平方差的描述),数字33并不是表现最好的一个.(gibbon:这里按照我的理解,照常理,应该是方差越小稳定,但是由于这里不清楚作者方差的计算公式,以及在哈希离散表,是不是离散度越大越好,所以不得而知这里的表现好是指方差值大还是指方差值小),但是数字33以及其他一些同样好的数字比如 17,31,63,127和129对于其他剩下的数字,在面对大量的哈希运算时,仍然有一个大大的优势,就是这些数字能够将乘法用位运算配合加减法来替换,这样的运算速度会提高.毕竟一个好的哈希算法要求既有好的分布,也要有高的计算速度,能同时达到这两点的数字很少.

PHP 相关文章推荐
第九节 绑定 [9]
Oct 09 PHP
PHP文本操作类
Nov 25 PHP
使用PHP socke 向指定页面提交数据
Jul 23 PHP
PHP的error_reporting错误级别变量对照表
Jul 08 PHP
PHP生成数组再传给js的方法
Aug 07 PHP
学习php设计模式 php实现桥梁模式(bridge)
Dec 07 PHP
Centos PHP 扩展Xchche的安装教程
Jul 09 PHP
Yii控制器中filter过滤器用法分析
Jul 15 PHP
探究Laravel使用env函数读取环境变量为null的问题
Dec 06 PHP
laravel 中如何使用ajax和vue总结
Aug 16 PHP
php curl简单采集图片生成base64编码(并附curl函数参数说明)
Feb 15 PHP
php5对象复制、clone、浅复制与深复制实例详解
Aug 14 PHP
php实现在线生成条形码示例分享(条形码生成器)
Dec 30 #PHP
md5 16位二进制与32位字符串相互转换示例
Dec 30 #PHP
微信扫描二维码登录网站代码示例
Dec 30 #PHP
浅谈PHP变量作用域以及地址引用问题
Dec 27 #PHP
一个好用的PHP验证码类实例分享
Dec 27 #PHP
PHP连接SQLServer2005方法及代码
Dec 26 #PHP
php截取中文字符串不乱码的方法
Dec 25 #PHP
You might like
PHP内核探索:变量存储与类型使用说明
2014/01/30 PHP
php实例分享之mysql数据备份
2014/05/19 PHP
PHP获取input输入框中的值去数据库比较显示出来
2016/11/16 PHP
Yii框架使用PHPExcel导出Excel文件的方法分析【改进版】
2019/07/24 PHP
动态控制Table的js代码
2007/03/07 Javascript
使用jQuery.Validate进行客户端验证(初级篇) 不使用微软验证控件的理由
2010/06/28 Javascript
javascript权威指南 学习笔记之null和undefined
2011/09/25 Javascript
jQuery实现当按下回车键时绑定点击事件
2014/01/28 Javascript
js获取客户端网卡的IP地址、MAC地址
2014/03/26 Javascript
初始Nodejs
2014/11/08 NodeJs
jQuery中outerWidth()方法用法实例
2015/01/19 Javascript
深入探讨javascript函数式编程
2015/10/11 Javascript
JS实现的表格行鼠标点击高亮效果代码
2015/11/27 Javascript
js简单网速测试方法完整实例
2015/12/15 Javascript
JavaScript中常用的验证reg
2016/10/13 Javascript
关于Iframe父页面与子页面之间的相互调用
2016/11/22 Javascript
js禁止浏览器页面后退功能的实例(推荐)
2017/09/01 Javascript
浅谈webpack性能榨汁机(打包速度优化)
2019/01/09 Javascript
js实现京东秒杀倒计时功能
2019/01/21 Javascript
Vue指令之 v-cloak、v-text、v-html实例详解
2019/08/08 Javascript
JavaScript实现电灯开关小案例
2020/03/30 Javascript
使用PDB简单调试Python程序简明指南
2015/04/25 Python
Python实现读取字符串按列分配后按行输出示例
2018/04/17 Python
详解python和matlab的优势与区别
2019/06/28 Python
Python把图片转化为pdf代码实例
2020/07/28 Python
html5 利用重力感应实现摇一摇换颜色可用来做抽奖等等
2014/05/07 HTML / CSS
美国儿童运动鞋和服装零售商:Kids Foot Locker
2017/08/05 全球购物
英国奢华护肤、美容和Spa品牌:Temple Spa
2019/11/02 全球购物
美国环保妈妈、儿童和婴儿用品购物网站:The Tot
2019/11/24 全球购物
手工制作的意大利皮革运动鞋:KOIO
2020/01/05 全球购物
结婚典礼证婚词
2014/01/11 职场文书
文秘人员工作职责
2014/01/31 职场文书
软件部经理岗位职责范本
2014/02/25 职场文书
公安局负责人查摆问题及整改方案
2014/09/27 职场文书
2014年乡镇纪委工作总结
2014/12/19 职场文书
节水宣传标语口号
2015/12/26 职场文书