1

作为练习,我尝试在 PHP 中实现 MD5。我知道 PHP 有一个内置函数,但我想阅读、运行和研究一个工作源。我发现这个脚本在取消注释适当的部分(以启用消息填充)并且相应地格式化数组(为了与我的 PHP 版本兼容)时效果很好。但是产生的哈希 - 尽管长度正确 - 不是 MD5。例如,零长度字符串的 MD5 散列应该是:

d41d8cd98f00b204e9800998ecf8427e

但是脚本返回的哈希值是:

85bd946a585af9fd3fb9eda68707c1d8

我尝试过其他字符串,但没有相关性。我一直在研究 MD5,所以对它的工作原理有一个合理的了解。我一直在审问剧本,但它似乎是合法的。我想我是在向另一个人大喊大叫,挑战发现这个脚本为什么没有返回 MD5。

4

1 回答 1

2

该脚本没有返回真正的 MD5 哈希值,因为旋转函数存在问题。

PHP 目前不提供原生的按位旋转函数。然而,可以通过组合左移结果和右移结果来实现按位旋转。但是,在负符号整数的右位移位期间,符号位被移入以保持操作数的符号不变;这会产生不必要的后果,并且可以使用位掩码来克服。

其中$x是输入值,$c是要移位的位数。所有值都是 32 位的。

原始代码:

`return ($x << $c) | ($x >> (32 - $c));`

新代码:

if($x < 0){
    return ($x << $c) | abs( ((pow(2, $c)) * -1) - ($x >> (32 - $c)));
} else { 
    return ($x << $c) |                            ($x >> (32 - $c)) ;
}

我特意在第 4 行留下了多个空格,以与第 2 行进行对比,以显示公式相似性和位掩码的存在(或不存在)。

三进制格式:

 return ($x < 0) ? (($x << $c) | abs( ((pow(2, $c)) * -1) - 
        ($x >> (32 - $c)))) : (($x << $c) | ($x >> (32 - $c)));
于 2016-10-25T13:57:42.967 回答