简体   繁体   English

PHP中的MD5脚本

[英]MD5 script in PHP

As an exercise, I'm attempting to implement MD5 in PHP. 作为练习,我尝试在PHP中实现MD5。 I know PHP has a built-in function for this but I would like to read, run and study a working source. 我知道PHP为此具有内置功能,但是我想阅读,运行和研究有效的源代码。 I found this script which works great when appropriate sections are uncommented (to enable message padding) and arrays are formatted accordingly (for compatibility for my version of PHP.) However the hash produced - despite being of correct length - is not MD5. 我发现此脚本在取消注释适当的部分(以启用消息填充)并相应地格式化数组(以与我的PHP版本兼容)时非常有用。但是,尽管长度正确,但生成的哈希不是MD5。 For example, the MD5 hash for a zero length string should be: 例如,零长度字符串的MD5哈希应为:

d41d8cd98f00b204e9800998ecf8427e d41d8cd98f00b204e9800998ecf8427e

but the hash returned by the script for the same is: 但是脚本返回的哈希值是:

85bd946a585af9fd3fb9eda68707c1d8 85bd946a585af9fd3fb9eda68707c1d8

I've tried other strings but there is no correlation. 我试过其他字符串,但没有关联。 I've been studying MD5 so have a reasonable knowledge of how it works. 我一直在研究MD5,因此对它的工作原理有一定的了解。 I've been interrogating the script but it seems legitimate. 我一直在询问脚本,但似乎合法。 I guess I'm giving a shout out to another up for the challenge of discovering why this script isn't returning MD5. 我想我正在大声疾呼,以发现这个脚本为什么不返回MD5的挑战。

This script wasn't returning genuine MD5 hashes because there lay an issue with the rotation function. 该脚本未返回真正的MD5哈希,因为旋转功能存在问题。

PHP currently doesn't offer native bitwise rotation function(s). PHP当前不提供本机按位旋转功能。 Nevertheless, bitwise rotation can be achieved by combining a left shift result and a right shift result. 然而,可以通过组合左移位结果和右移位结果来实现按位旋转。 However, during right bit shifts on negative signed integers the sign bit is shifted in for sign-preservation of the operand; 但是,在负负整数上右移位时,会将符号位移入以保留操作数。 this has unwanted consequences and is overcome using a bit mask. 这会产生不良后果,并使用位掩码可以解决。

Where $x is input value and $c is number of bits to shift. 其中$x是输入值, $c是要移位的位数。 All values are 32-bit. 所有值均为32位。

Original Code: 原始代码:

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

New Code: 新代码:

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

I've deliberately left multiple spaces on line 4 to contrast with line 2 to show formula similarity and presence (or absence) of the bit mask. 我故意在第4行上留下了多个空格,以与第2行进行对比,以显示公式的相似性和位掩码的存在(或不存在)。

Ternary formatted: 三进制格式:

 return ($x < 0) ? (($x << $c) | abs( ((pow(2, $c)) * -1) - 
        ($x >> (32 - $c)))) : (($x << $c) | ($x >> (32 - $c)));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM