【问题标题】:Python 2 vs 3. Same inputs, different results. MD5 hashPython 2 vs 3。相同的输入,不同的结果。 MD5 哈希
【发布时间】:2016-12-09 20:46:03
【问题描述】:

Python 3 代码:

def md5hex(data):
    """ return hex string of md5 of the given string """
    h = MD5.new()
    h.update(data.encode('utf-8'))
    return b2a_hex(h.digest()).decode('utf-8')

Python 2 代码:

def md5hex(data):
    """ return hex string of md5 of the given string """
    h = MD5.new()
    h.update(data)
    return b2a_hex(h.digest())

输入python 3:

>>> md5hex('bf5¤7¤8¤3')
'61d91bafe643c282bd7d7af7083c14d6'

输入python 2:

>>> md5hex('bf5¤7¤8¤3')
'46440745dd89d0211de4a72c7cea3720'

怎么了?

编辑:

def genurlkey(songid, md5origin, mediaver=4, fmt=1):
    """ Calculate the deezer download url given the songid, origin and media+format """
    data = b'\xa4'.join(_.encode("utf-8") for _ in [md5origin, str(fmt), str(songid), str(mediaver)])
    data = b'\xa4'.join([md5hex(data), data])+b'\xa4'
    if len(data)%16:
        data += b'\x00' * (16-len(data)%16)
    return hexaescrypt(data, "jo6aey6haid2Teih").decode('utf-8')

所有这些问题都是从另一个函数中的 python 2 代码中的这个 b'\xa4' 开始的。这个字节在 python 3 中不起作用。

用那个我得到正确的 MD5 哈希...

【问题讨论】:

  • 您是否尝试过使用u 前缀字符串?
  • @NilsWerner,是的。结果相同。
  • 你试过from __future__ import unicode_literals 吗?
  • 使用 \x 符号我得到相同的校验和:h=md5("bf5\xc2\xa47\xc2\xa48\xc2\xa43"); h.hexdigest() => 61d91....
  • @Jean-FrançoisFabre 问题是在 python 2 代码中,它的 b'\xa4',它在 python 3 中不起作用。

标签: python python-2.7 python-3.x md5


【解决方案1】:

改用hashlib 和与语言无关的实现:

import hashlib
text = u'bf5¤7¤8¤3'
text = text.encode('utf-8')
print(hashlib.md5(text).hexdigest())

在 Python 2/3 中工作,结果相同:

Python2:

'61d91bafe643c282bd7d7af7083c14d6'

Python3(通过 repl.it):

'61d91bafe643c282bd7d7af7083c14d6'

您的代码失败的原因是编码的字符串与未编码的字符串相同:您只是为 Python 3 编码。


如果你需要它来匹配未编码的 Python 2:

import hashlib
text = u'bf5¤7¤8¤3'
print(hashlib.md5(text.encode("latin1")).hexdigest())

作品:

46440745dd89d0211de4a72c7cea3720

Python 2 的默认编码是 latin1 而不是 utf-8

【讨论】:

  • 我用生成“¤”字符的问题编辑了我的问题。正确的结果应该是 '46440745dd89d0211de4a72c7cea3720'。
  • @EduardoM 是否有某种原因是“正确”的结果?只要对相同的输入给出相同的结果,哈希值应该是无关紧要的。
  • 这是因为原始代码在python 2中。我声明了编码,因为代码返回了一个KeyError TypeError: Unicode-objects must be encoded before hashing在python 2中,正确的,它不需要编码。
  • @EduardoM 因为 Python 3 不支持您想要做的事情。
  • 应该有一些解决方法......这不可能在python 3中获得正确的哈希吗?
【解决方案2】:

python3 中的默认编码是 Unicode。在 python 2 中,它是 ASCII。因此,即使字符串在读取时匹配,它们也会以不同的方式呈现。

【讨论】:

  • 有什么解决办法吗?我需要在 python 2 代码中得到的相同结果。问题在于“¤”字符。
  • 你是否在 python2 源代码中声明了编码?
  • 我只是把它放在 python 3 源代码中,因为代码给出了 TypeError:TypeError: Unicode-objects must be encoded before hashing
  • 试着把它放在 #/usr/bin/python 或类似的东西之后(第一行之后)# -*- coding: utf-8 -*- 然后将文件保存为 utf-8。然后检查他们两个之间是否有区别:)
  • 问题只是编码类型。它是 latin1 而不是 utf-8。还是谢谢
猜你喜欢
  • 2018-09-05
  • 1970-01-01
  • 2021-05-04
  • 1970-01-01
  • 2018-03-23
  • 1970-01-01
  • 2017-01-24
  • 2023-04-05
  • 1970-01-01
相关资源
最近更新 更多