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 相关文章推荐
Oracle 常见问题解答
Oct 09 PHP
打造计数器DIY三步曲(下)
Oct 09 PHP
mysql建立外键
Nov 25 PHP
php 数组的创建、调用和更新实现代码
Mar 09 PHP
用php随机生成福彩双色球号码的2种方法
Feb 04 PHP
PHP实现删除字符串中任何字符的函数
Aug 11 PHP
PHP 7的一些引人注目的新特性简单介绍
Nov 08 PHP
在WordPress中安装使用视频播放器插件Hana Flv Player
Jan 04 PHP
PHP+Ajax实现无刷新分页实例详解(附demo源码下载)
Apr 07 PHP
PHP strip_tags() 去字符串中的 HTML、XML 以及 PHP 标签的函数
May 22 PHP
php使用正则表达式去掉html中的注释方法
Nov 03 PHP
PHP中的self关键字详解
Jun 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
PHP中绘制图像的一些函数总结
2014/11/19 PHP
header与缓冲区之间的深层次分析
2016/07/30 PHP
用js判断用户浏览器是否是XP SP2的IE6
2007/03/08 Javascript
『jQuery』.html(),.text()和.val()的概述及使用
2013/04/22 Javascript
原生JS实现加入收藏夹的代码
2013/10/24 Javascript
js动态改变select选择变更option的index值示例
2014/07/10 Javascript
纯Javascript实现ping功能的方法
2015/03/20 Javascript
jquery中的工具使用方法$.isFunction, $.isArray(), $.isWindow()
2015/08/09 Javascript
jQuery选择器用法实例详解
2015/12/17 Javascript
简单谈谈axios中的get,post方法
2017/06/25 Javascript
Express+Nodejs 下的登录拦截实现代码
2017/07/01 NodeJs
详解webpack的proxyTable无效的解决方案
2018/06/15 Javascript
如何在微信小程序中使用骨架屏的步骤
2020/06/12 Javascript
如何利用nodejs自动定时发送邮件提醒(超实用)
2020/12/01 NodeJs
[01:01:36]Optic vs paiN 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
利用python代码写的12306订票代码
2015/12/20 Python
Win10下Python环境搭建与配置教程
2016/11/18 Python
python 实现在txt指定行追加文本的方法
2018/04/29 Python
Python爬虫实现(伪)球迷速成
2018/06/10 Python
python递归全排列实现方法
2018/08/18 Python
用Q-learning算法实现自动走迷宫机器人的方法示例
2019/06/03 Python
python协程gevent案例 爬取斗鱼图片过程解析
2019/08/27 Python
Python从入门到精通之环境搭建教程图解
2019/09/26 Python
如何在django中运行scrapy框架
2020/04/22 Python
如何把外网python虚拟环境迁移到内网
2020/05/18 Python
python自定义函数def的应用详解
2020/06/03 Python
python使用re模块爬取豆瓣Top250电影
2020/10/20 Python
HTML5标签嵌套规则详解【必看】
2016/04/26 HTML / CSS
美国隐形眼镜零售商:LensPure
2019/03/10 全球购物
《哪吒闹海》教学反思
2014/02/28 职场文书
《风筝》教学反思
2014/04/10 职场文书
广播体操比赛口号
2014/06/10 职场文书
个人三严三实对照检查材料
2014/09/25 职场文书
车间主任岗位职责范本
2015/04/08 职场文书
在 SQL 语句中处理 NULL 值的方法
2021/06/07 SQL Server
postgres之jsonb属性的使用操作
2021/06/23 PostgreSQL