使用不同结果的MD5哈希

21
我正在尝试将一些字符串编码为 MD5,但我注意到以下情况:
对于字符串:“123456çñ”
http://www.md5.net, www.md5.cz和md5generator.net这样的网站的计算结果为“66f561bb6b68372213dd9768e55e1002”。
而像http://www.adamek.biz/md5-generator.php,7thspace.com/webmaster_tools/online_md5_encoder.html和 md5.rednoize.com 这些网站的计算结果为“9e6c9a1eeb5e00fbf4a2cd6519e0cfcb”。
我需要使用标准的MD5进行编码,原因是我需要将我的结果与其他系统连接。哪个散列值才是正确的?
先行致谢。

4
我感觉这是一个编码问题... - user541686
4个回答

24

我猜问题出在不同的文本编码上。你展示的字符串无法使用ANSI编码表示 - 它需要UTF-16或UTF-8。选择后者之一会导致字符串有不同的字节表示,从而产生不同的哈希值。

请记住,MD5对字节进行哈希,而不是字符 - 在将字节提供给MD5之前,你可以自己选择如何将这些字符编码为字节。如果你想与其他系统互操作,你必须使用与那些系统相同的编码。


6
哦,你比我快了25秒 :) 这会教训我不要浪费时间推荐SHA2。 - Cameron Skinner

8

让我们使用Python来理解这个问题。

>>> '123456çñ'
'123456\xc3\xa7\xc3\xb1'
>>> 'ç'
'\xc3\xa7'
>>> 'ñ'
'\xc3\xb1'

在上面的输出中,我们看到了对'ç'和'ñ'的UTF-8编码。
>>> md5('123456çñ').digest().encode('hex')
'66f561bb6b68372213dd9768e55e1002'

因此,当我们计算UTF-8编码数据的MD5散列时,我们会得到第一个结果。

>>> u'ç'
u'\xe7'
>>> u'ñ'
u'\xf1'

在这里,我们看到了'ç'和'ñ'的Unicode代码点。

>>> md5('123456\xe7\xf1').digest().encode('hex')
'9e6c9a1eeb5e00fbf4a2cd6519e0cfcb'

因此,当我们计算字符串中每个字符的Unicode代码点表示形式(可能是ISO-8859-1编码)的数据的MD5哈希值时,会得到第二个结果。

因此,第一个网站计算的是UTF-8编码数据的哈希值,而第二个网站则不是。


6
如果我尝试:
echo "123456çñ<br />";
echo "utf-8 : ".md5("123456çñ")."<br />";
echo "ISO-8859-1 : ".md5(iconv("UTF-8", "ISO-8859-1","123456çñ"))."<br />";

它会给出以下结果:
123456çñ
utf-8 : 66f561bb6b68372213dd9768e55e1002
ISO-8859-1 : 9e6c9a1eeb5e00fbf4a2cd6519e0cfcb

第一个网站使用ISO-8859-1编码字符串,而第二个网站使用UTF-8编码。

3
我猜这些站点中有一些没有正确处理非ASCII字符。如果您使用标准的MD5库,那么只要您和您连接到的系统在使用哪种字符编码上达成一致,您就可以放心使用。
顺便说一下,现在不建议再使用MD5了。如果这是用于加密目的,那么您真的应该转向SHA2。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接