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
Dec 23 PHP
PHP生成HTML静态页面实例代码
Aug 31 PHP
php&amp;mysql 日期操作小记
Feb 27 PHP
PHP常用的文件操作函数经典收藏
Apr 02 PHP
php设计模式之单例、多例设计模式的应用分析
Jun 30 PHP
浅析Mysql 数据回滚错误的解决方法
Aug 05 PHP
简单说说PHP优化那些事(经验分享)
Nov 27 PHP
高质量PHP代码的50个实用技巧必备(下)
Jan 22 PHP
Zend Framework过滤器Zend_Filter用法详解
Dec 09 PHP
PHP简单实现遍历目录下特定文件的方法小结
May 22 PHP
tp5(thinkPHP5框架)使用DB实现批量删除功能示例
May 28 PHP
thinkphp 框架数据库切换实现方法分析
May 18 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
CURL状态码列表(详细)
2013/06/27 PHP
php使用iconv中文截断问题的解决方法
2015/02/11 PHP
php中用unset销毁变量并释放内存
2020/05/10 PHP
Extjs学习笔记之五 一个小细节renderTo和applyTo的区别
2010/01/07 Javascript
jQuery ajax(复习)—Baidu ajax request分离版
2013/01/24 Javascript
javascript获取URL参数与参数值的示例代码
2013/12/20 Javascript
浅谈Javascript中substr和substring的区别
2015/09/30 Javascript
浅谈javascript:两种注释,声明变量,定义函数
2016/09/29 Javascript
JavaScript之cookie技术详解
2016/11/18 Javascript
jQuery中的siblings()是什么意思(推荐)
2016/12/29 Javascript
jQuery实现简单的滑动导航代码(移动端)
2017/05/22 jQuery
原生JS实现ajax与ajax的跨域请求实例
2017/12/01 Javascript
用node撸一个监测复联4开售短信提醒的实现代码
2019/04/10 Javascript
JS将时间秒转换成天小时分钟秒的字符串
2019/07/10 Javascript
vue集成chart.js的实现方法
2019/08/20 Javascript
javascript实现下拉菜单效果
2021/02/09 Javascript
[47:04]LGD vs infamous Supermajor小组赛D组 BO3 第二场 6.3
2018/06/04 DOTA
Python数据结构之Array用法实例
2014/10/09 Python
python简单分割文件的方法
2015/07/30 Python
centos6.4下python3.6.1安装教程
2017/07/21 Python
Python根据已知邻接矩阵绘制无向图操作示例
2018/06/23 Python
对python中if语句的真假判断实例详解
2019/02/18 Python
Python常用爬虫代码总结方便查询
2019/02/25 Python
创建Django项目图文实例详解
2019/06/06 Python
python RC4加密操作示例【测试可用】
2019/09/26 Python
python 类之间的参数传递方式
2019/12/20 Python
基于Tensorflow:CPU性能分析
2020/02/10 Python
丝绸和人造花卉、植物和树木:Nearly Natural
2018/11/28 全球购物
俄罗斯在线购买飞机票、火车票、巴士票网站:Tutu.ru
2020/03/16 全球购物
什么是岗位职责
2013/11/12 职场文书
《故乡》教学反思
2014/04/10 职场文书
喝酒驾驶检讨书
2014/10/01 职场文书
2015年大学生工作总结
2015/04/21 职场文书
盲山观后感
2015/06/11 职场文书
2016年清明节网上祭英烈活动总结
2016/04/01 职场文书
python中super()函数的理解与基本使用
2021/08/30 Python