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 相关文章推荐
php miniBB中文乱码问题解决方法
Nov 25 PHP
php动态生成JavaScript代码
Mar 09 PHP
php更改目录及子目录下所有的文件后缀扩展名的代码
Oct 12 PHP
PHP优于Node.js的五大理由分享
Sep 15 PHP
php数据库备份还原类分享
Mar 20 PHP
PHP获取时间排除周六、周日的两个方法
Jun 30 PHP
PHP准确取得服务器IP地址的方法
Jun 02 PHP
PHP中功能强大却很少使用的函数实例小结
Nov 10 PHP
PHP读取zip文件的方法示例
Nov 17 PHP
thinkphp5框架结合mysql实现微信登录和自定义分享链接与图文功能示例
Aug 13 PHP
php ActiveMQ的安装与使用方法图文教程
Feb 23 PHP
PHP+MySql实现一个简单的留言板
Jul 19 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 模拟GMAIL,HOTMAIL(MSN),YAHOO,163,126邮箱登录的详细介绍
2013/06/18 PHP
php项目中百度 UEditor 简单安装调试和调用
2015/07/15 PHP
PHP实现无限级分类(不使用递归)
2015/10/22 PHP
Yii框架实现记录日志到自定义文件的方法
2017/05/23 PHP
PHP7.3.10编译安装教程
2019/10/08 PHP
php+iframe 实现上传文件功能示例
2020/03/04 PHP
jqPlot Option配置对象详解
2009/07/25 Javascript
js获取当前页面的url网址信息
2014/06/12 Javascript
JavaScript中获取鼠标位置相关属性总结
2014/10/11 Javascript
ztree获取当前选中节点子节点id集合的方法
2015/02/12 Javascript
JS实现全屏的四种写法
2016/12/30 Javascript
Angular通过angular-cli来搭建web前端项目的方法
2017/07/27 Javascript
zTree获取当前节点的下一级子节点数实例
2017/09/05 Javascript
最新Javascript程序员面试试题和解题方法
2017/11/23 Javascript
解决jquery的ajax调取后端数据成功却渲染失败的问题
2018/08/08 jQuery
vue2.0 中使用transition实现动画效果使用心得
2018/08/13 Javascript
bootstrap实现点击删除按钮弹出确认框的实例代码
2018/08/16 Javascript
小程序实现点击tab切换左右滑动
2020/11/16 Javascript
使用JS实现鼠标放上图片进行放大离开实现缩小功能
2021/01/27 Javascript
[40:03]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第一场 8.21
2018/08/22 DOTA
在Python中处理XML的教程
2015/04/29 Python
python实现机械分词之逆向最大匹配算法代码示例
2017/12/13 Python
让代码变得更易维护的7个Python库
2018/10/09 Python
python中 * 的用法详解
2019/07/10 Python
python pycharm的安装及其使用
2019/10/11 Python
Python通过4种方式实现进程数据通信
2020/03/12 Python
Python decorator拦截器代码实例解析
2020/04/04 Python
Python在centos7.6上安装python3.9的详细教程(默认python版本为2.7.5)
2020/10/15 Python
html5的画布canvas——画出弧线、旋转的图形实例代码+效果图
2013/06/09 HTML / CSS
使用html2canvas.js实现页面截图并显示或上传的示例代码
2018/12/18 HTML / CSS
驴妈妈旅游网:中国新型的B2C旅游电子商务网站
2016/08/16 全球购物
图库照片、免版税图片、矢量艺术、视频片段:Depositphotos
2019/08/02 全球购物
用C#语言写出与SQLSERVER访问时的具体过程
2013/04/16 面试题
仓库主管的岗位职责
2013/12/04 职场文书
台风停课通知
2015/04/24 职场文书
2016年小学植树节活动总结
2016/03/16 职场文书