Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的Hashlib md5返回某些unicode字符的不正确摘要?_Python_Unicode_Hash_Md5 - Fatal编程技术网

python中的Hashlib md5返回某些unicode字符的不正确摘要?

python中的Hashlib md5返回某些unicode字符的不正确摘要?,python,unicode,hash,md5,Python,Unicode,Hash,Md5,我一直在玩python和Java的MD5实现,遇到了这个让我困惑的怪癖 以下python脚本说明了该问题: # -*- coding: utf-8 -*- import hashlib def md5hash(x): m = hashlib.md5() m.update(x) return m.hexdigest() print md5hash('\xdb') print md5hash('Û') 输出: 98fd00d788afe2a5fa5e4f8e1666638b 31e

我一直在玩python和Java的MD5实现,遇到了这个让我困惑的怪癖

以下python脚本说明了该问题:

# -*- coding: utf-8 -*-
import hashlib

def md5hash(x):
  m = hashlib.md5()
  m.update(x)
  return m.hexdigest()

print md5hash('\xdb')
print md5hash('Û')
输出:

98fd00d788afe2a5fa5e4f8e1666638b
31ecfb09f120720a55d96a2034f5d00b
31ecfb09f120720a55d96a2034f5d00b
31ecfb09f120720a55d96a2034f5d00b
考虑到
Û
应该等同于
\xdb
,我希望这两个摘要是等效的。我用Java构建了一个等效的实现,以获得更多的洞察力:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Test {
  public static void main(String[] args) throws Exception {
    MessageDigest m = MessageDigest.getInstance("MD5");

    m.update("\u00db".getBytes());
    System.out.println(bytesToHex(m.digest()));

    m.update("Û".getBytes());
    System.out.println(bytesToHex(m.digest()));
  }

  final protected static char[] hexArray = "0123456789abcdef".toCharArray();
  public static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for ( int j = 0; j < bytes.length; j++ ) {
      int v = bytes[j] & 0xFF;
      hexChars[j * 2] = hexArray[v >>> 4];
      hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
  }
}
Java的输出与预期一致。这让我相信
md5hash('\xdb')
输出的结果不正确,但我不确定我遗漏了什么。有什么想法吗

考虑到
Û
应该等同于
\xdb
,我希望这两个摘要是等效的

Û是UTF-8中的
C3 9B
,您似乎正在使用它(这是您声明的编码)<代码>数据库将是ISO-8859-1

导入hashlib >>>hashlib.md5(b'\xc3\x9b').hexdigest() “31ECFB09F120720720A55D96A2034F5D00B”
塔达

你的假设是错误的。您的Python源代码是从以下内容开始的:

# -*- coding: utf-8 -*-
在这种情况下,
Û
不等于
\xdb
;而是两个字节:

>>> u'Û'.encode('utf8')
'\xc3\x9b'
Python在这里是完全一致的:

>>> import hashlib
>>> hashlib.md5('\xc3\x9b').hexdigest()
'31ecfb09f120720a55d96a2034f5d00b'
>>> hashlib.md5('\xdb').hexdigest()
'98fd00d788afe2a5fa5e4f8e1666638b'
在Java中,您从Unicode代码点开始,将其转换为UTF-8字节:

"\u00db".getBytes()
Python的等价物是使用
unicode
字符串文字和
\uhhh
\xhh
转义序列:

>>> u'\u00db'.encode('utf8')
'\xc3\x9b'
>>> u'\xdb'.encode('utf8')
'\xc3\x9b'
注意
u
前缀以生成
unicode
字符串
\xdb
不带
u
前缀是一个字节字符串,而不是Unicode码点,只有将其解码为拉丁语1,才能得到相同的Unicode字符串:

>>> '\xdb'.decode('latin1')
u'\xdb'
>>> '\xdb'.decode('latin1').encode('utf8')
'\xc3\x9b'
你可能想学习Python和Unicode;见:

  • 内德·巴奇尔德

为了完整起见:

  • 乔尔斯波尔斯基

假设
Û
应该等同于
\xdb
。这就是问题所在。
>>打印'\xdb'
产生
:关于编码错误的简单提示。@JulienPalard:这取决于您的控制台或终端配置。如果我将终端设置为使用拉丁语-1,则
print
将完全正确。@MartijnPieters您是对的,即使今天有人使用拉丁语1,也不能,对不起,很容易出错:-P
printf$'\xdb'| iconv-f latin1-t utf8 | hextdump-C
将您的拉丁语表示形式“\xdb”转换为utf8(\xC3\x9B),这个回答是正确的,“\xdb”是拉丁文的表示形式。@JulienPalard:不重要的注意:
$
使
printf
变得多余,因此您可以使用
echo$'\xdb'
printf'\xdb'
。您是对的,我总是使用bash语法进行转义,这样我就可以在任何地方使用它们,但我也使用printf来避免“\n”对于我的hextumps的可读性,这两种方法都有效。(我不使用echo-n
,不可携带)。