【问题标题】:Python, get base64-encoded MD5 hash of an image objectPython,获取图像对象的 base64 编码的 MD5 哈希
【发布时间】:2015-08-16 19:08:04
【问题描述】:

我需要获取一个对象的 base64 编码的 MD5 哈希,其中该对象是存储为文件 fname 的图像。

我试过这个:

def get_md5(fname):
    hash = hashlib.md5()
    with open(fname) as f:
        for chunk in iter(lambda: f.read(4096), ""):
            hash.update(chunk)
    return hash.hexdigest().encode('base64').strip()

但是,我认为这是不对的,因为它返回的字符串包含太多字符。我的理解是它需要 24 个字符长。我明白了

NjJiM2RlOWMzOTYxYmM3MDI5Y2Q1NzdjOTQ5YWRlYTQ=

我也尝试了其他一些类似的方法,例如,一种不执行块循环的方法。它们都返回相同的字符串。

(我后来需要 base64 编码的 MD5 哈希的操作失败了,我想这可能是原因。)

【问题讨论】:

  • 你试过二进制输出而不是十六进制输出吗?
  • 你的意思是 .digest() 而不是 hexdigest()?那行得通!想写答案吗? :)

标签: python hash md5


【解决方案1】:

我能够通过使用digest() 而不是hexdigest() 使其工作。那么最后一行变成:

return hash.digest().encode('base64').strip()

结果是 24 个字符长,并且被谷歌云存储传输接受,这需要一个 base64 编码的 MD5 哈希。

对于 Python 3(来自下面的评论):

import base64;  
return base64.b64encode(h.digest()).decode()

【讨论】:

  • 在 python 3 中这不起作用:*** AttributeError: 'bytes' object has no attribute 'encode'。这有效:import base64; base64.b64encode(h.digest()).decode()
【解决方案2】:

首先,base64 编码使字符串更长。 (使用 IPython 和 Python 3 的示例):

In [1]: s = '123456789012345678901234'

In [2]: len(s)
Out[2]: 24

In [3]: import base64

In [4]: e = base64.b64encode(s.encode('utf8'))

In [5]: len(e)
Out[5]: 32

In [6]: e
Out[6]: b'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0'

使用 base64 编码,每 6 位输入可获得 8 位输出。

In [7]: 32/24
Out[7]: 1.333

In [8]: 8/6
Out[8]: 1.333

base64 字母表使用 64(或 2**6)个不同的符号。 通常它们包括小写和大写字母,数字 0-9。这留下了两个额外的必需符号和一个填充字符。 通常+/ 用作符号,但也有变化。尤其是在 UNIX 或 MS-Windows 文件名中不允许使用 /

第二,使用十六进制表示加倍字节串的长度;一个字节的十六进制表示可以在 00 和 FF 之间变化。示例(再次使用 IPython 和 Python 3):

In [1]: import hashlib

In [2]: s = b'this is a simple test'

In [3]: len(hashlib.md5(s).digest())
Out[3]: 16

In [4]: len(hashlib.md5(s).hexdigest())
Out[4]: 32

如果你还是要使用 base64 编码,那么使用hexdigest() 是没有意义的。

【讨论】:

    【解决方案3】:

    我正在为浏览器的 CSP 哈希生成带有 base64 编码的内联 JavaScript 哈希,因此上述接受的答案给出了以下错误。原因是所有类型的字符串都没有处理好。

    AttributeError: 'bytes' 对象没有属性 'encode'

    因为 Unicode 对象必须在散列之前进行编码。我在下面的代码中通过 inline.encode('utf-8') 对其进行编码。

    要解决该问题,请使用以下方式。这就像一个魅力。

    import hashlib
    import base64
    
    base64hash=base64.b64encode(hashlib.sha256(inline.encode('utf-8')).digest())
    sha = "sha256-" + base64hash.decode("utf-8")
    print(sha)
    

    ==> 这是为使用 base64 编码的字符串生成 sha256 哈希。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-14
      • 2013-08-09
      • 2016-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-04
      • 2010-12-13
      相关资源
      最近更新 更多