9
6

hash()为什么比md5()要快?(已过时)

Author Jessica     Category PHP     Tags , ,

上篇文章中我们说了 hash要比md5快很多 为什么呢?

我就去看了下PHP的源码..

给我安慰的是 它们用的算法是一样的..这个不用想就知道..md5的算法就是那样..

但是为什么会出现这么大的速度诧异呢?

顺便提一下 这两个算法实现的代码我就不贴了 分别是\ext\hash\hash_md.c与\ext\standard\md5.c

想看的可以自己下载份PHP的源码比较下.

接上面.为什么速度会这么大呢?

我仔细比对了一下..发现代码几乎一致..令我十分郁闷..

再仔细看看 有个诧异..

hash中

1
2
3
4
5
6
if (raw_output) {
	RETURN_STRINGL(digest, 16, 1);
} else {
	make_digest(md5str, digest);
	RETVAL_STRING(md5str, 1);
}

md5中

1
2
3
4
5
6
if (raw_output) {
	RETURN_STRINGL(digest, 16, 1);
} else {
	make_digest_ex(md5str, digest, 16);
	RETVAL_STRING(md5str, 1);
}

我们发现 一个使用的是make_digest而另外一个是make_digest_ex

我们去看make_digest的代码 往上看 看到hash中的make_digest调用的是php_hash_bin2hex

而md5中的make_digest_ex没有任何调用 就是一个函数..

我现在把这两个函数写出来

这个是md5的

1
2
3
4
5
6
7
8
9
10
11
PHPAPI void make_digest_ex(char *md5str, unsigned char *digest, int len)
{
	static const char hexits[17] = "0123456789abcdef";
	int i;
 
	for (i = 0; i < len; i++) {
		md5str[i * 2]       = hexits[digest[i] >> 4];
		md5str[(i * 2) + 1] = hexits[digest[i] &  0x0F];
	}
	md5str[len * 2] = '\0';
}

下面这个是hash调用的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
PHP_HASH_API void make_digest(char *md5str, unsigned char *digest)
{
	php_hash_bin2hex(md5str, digest, 16);
	md5str[32] = '\0';
}
static inline void php_hash_bin2hex(char *out, const unsigned char *in, int in_len)
{
	static const char hexits[17] = "0123456789abcdef";
	int i;
 
	for(i = 0; i < in_len; i++) {
		out[i * 2]       = hexits[in[i] >> 4];
		out[(i * 2) + 1] = hexits[in[i] &  0x0F];
	}
}

看到什么区别了吗?在md5中函数的申明是PHPAPI

我们到php.h中查找这个宏的定义是

1
2
3
4
5
#	ifdef PHP_EXPORTS
#	define PHPAPI __declspec(dllexport)
#	else
#	define PHPAPI __declspec(dllimport)
#	endif

我们看到PHP把这个函数到处到dll中了..所以调用的时候会慢一点

而hash中 直接将php_hash_bin2hex声明的是static inline.. inline的效率与dll的效率可想而知.

为了验证我的猜想 晚上回家换linux编译下试试:) 未完待续..

————————————我是杯具分割线—————————————-

刚才没事儿就去linux下编译了自己的一份测试了下..结果让我倒塌.

先不说结果.. 先自我批评 自我忏悔..

我上个帖子中的测试结果 并没有自己实际的去测试.而是在手册中 看到这样的评论.就直接拿出来.并没有证明其正确性.

我现在用相同的代码测试结果是:

0.24335312843323: hash/md5
0.17165088653564: md5
0.26487493515015: hash/sha1
0.19068503379822: sha1
————————
0.26703000068665: hash/md5
0.20045804977417: md5
0.29354310035706: hash/sha1
0.21823596954346: sha1

我们看到 hash要比md5慢 跟上次我贴的结果完全相反..

害我折腾去重新编译验证..结果发现验证的结果是相反的..

我回头再看那个人的评论 发现那个人是2007年评论的.而且他并没有留下他的PHP版本.

所以我猜想.PHP在一些版本中 确实存在这个问题..但是现在..我们后来使用的版本.已经修正了这个问题.

但是源码中.为什么函数不是inline反而那么快呢?

读通代码后.发现这个函数没起到什么影响MD5算法的关键..这个函数只是把MD5计算后的2进制改变为16进制.

也就是说 在这个函数执行之前..PHP已经将字符串进行MD5加密完成了..

所以不会起到什么关键性的速度提升..

无论如何..这次太唐突了..

阿米托佛

6 Comments to “ hash()为什么比md5()要快?(已过时) ”

  • 甲骨文 2010年03月9日于13:08

    研究的真细~~看来平时工作不忙么,要给你加点任务了。

    • Jessica 2010年03月9日于13:53

      哈哈.. 抽空抽空..

  • iminto 2010年03月9日于19:00

    发现这个函数没起到什么影响MD5算法的关键.
    应该是这样的

  • cnan 2010年03月9日于20:10

    今天看了上一篇文章后我在我的机子上测了一下,发现hash要快一些,难道我因为文章的先入为主影响看错了?

    我的环境是centos5.4+apache2.x+php5.3

    看样明天回去我要再看看。

  • freetao 2010年03月10日于21:39

    额。。还没到能看得懂的程度,
    不过博主怎么能不说一声就将俺的友链给去了呢?太伤心了~~

    • Jessica 2010年03月11日于09:19

      啊…这不是刚换了wp 好多链接还没有加上 这就给你加上 嘿嘿

Post comment

分类目录

最近文章

最近评论

文章索引模板

标签

.net AJAX button Comet CSS Discuz! DIV+CSS Flash Form Google HTML编辑器 IE8 Java JavaScript jQuery JSP md5 MySQLReback Oracle PHP php-fpm PNG Punny SkiyoTabs tab TagCloud Vista Web2.0 Windows7 上传 加密 变量 图标 本站原创 模板 模板引擎 源码 登录 短网址 石家庄 算法 编译 面向对象 魔术方法

链接表