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 图片上添加透明度渐变的效果
Jun 29 PHP
php小偷相关截取函数备忘
Nov 28 PHP
php中hashtable实现示例分享
Feb 13 PHP
destoon实现底部添加你是第几位访问者的方法
Jul 15 PHP
Laravel 5框架学习之向视图传送数据(进阶篇)
Apr 08 PHP
smarty内部日期函数html_select_date()用法实例分析
Jul 08 PHP
PHP+mysql+ajax轻量级聊天室实现方法详解
Oct 17 PHP
magento后台无法登录解决办法的两种方法
Dec 09 PHP
Yii全局函数用法示例
Jan 22 PHP
PHP的mysqli_select_db()函数讲解
Jan 23 PHP
PHP常用工具函数小结【移除XSS攻击、UTF8与GBK编码转换等】
Apr 27 PHP
laravel清除视图缓存的代码
Oct 23 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
Yii获取当前url和域名的方法
2015/06/08 PHP
php微信公众平台开发(一) 配置接口
2016/12/06 PHP
php把文件设置为插件的技巧方法
2020/02/03 PHP
javascript 兼容鼠标滚轮事件
2009/04/07 Javascript
关于JavaScript中string 的replace
2013/04/12 Javascript
javascript:void(0)的作用示例介绍
2013/10/28 Javascript
js获得当前时区夏令时发生和终止的时间代码
2014/02/23 Javascript
实例讲解JavaScript中call、apply、bind方法的异同
2016/09/13 Javascript
JavaScript中this的四个绑定规则总结
2016/09/26 Javascript
仿iframe效果Aajx文件上传实例
2016/11/18 Javascript
纯js的右下角弹窗实例
2017/03/12 Javascript
CentOS环境中MySQL修改root密码方法
2018/01/07 Javascript
VueAwesomeSwiper在VUE中的使用以及遇到的一些问题
2018/01/11 Javascript
使用vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)功能
2018/03/22 Javascript
jQuery实现动画、消失、显现、渐出、渐入效果示例
2018/09/06 jQuery
Koa代理Http请求的示例代码
2018/10/10 Javascript
详解Nodejs get获取远程服务器接口数据
2019/03/26 NodeJs
详解ES6中class的实现原理
2020/10/03 Javascript
详解Python中DOM方法的动态性
2015/04/11 Python
python打开url并按指定块读取网页内容的方法
2015/04/29 Python
举例详解Python中yield生成器的用法
2015/08/05 Python
python队列queue模块详解
2018/04/27 Python
Python实现合并两个有序链表的方法示例
2019/01/31 Python
python矩阵运算,转置,逆运算,共轭矩阵实例
2020/05/11 Python
基于Python3读写INI配置文件过程解析
2020/07/23 Python
用CSS3实现瀑布流布局的示例代码
2017/11/10 HTML / CSS
针对HTML5的Web Worker使用攻略
2015/07/12 HTML / CSS
div或img图片高度随宽度自适应的方法
2020/02/06 HTML / CSS
阿联酋航空假期:Emirates Holidays
2018/03/20 全球购物
Ralph Lauren意大利官方网站:时尚界最负盛名的品牌之一
2018/10/18 全球购物
房屋认购协议书
2015/01/29 职场文书
高中生思想道德自我评价
2015/03/09 职场文书
思品教学工作总结
2015/08/10 职场文书
优秀学生主要事迹怎么写
2015/11/04 职场文书
Python 实现定积分与二重定积分的操作
2021/05/26 Python
改造DE1103三步曲
2022/04/07 无线电