Python,获取图像对象的Base64编码的MD5哈希值

16

我需要获取一个对象的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哈希,但失败了,我想这可能就是原因。


你尝试过使用二进制输出而不是十六进制输出吗? - Caramiriel
1
你是不是想用 .digest() 而不是 hexdigest()?那个可行!你想写答案吗? :) - user984003
3个回答

25

我通过使用digest()而非hexdigest()使其工作。然后最后一行变成:

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

结果为24个字符长,被Google云存储传输所接受,而该传输需要一个base64编码的MD5哈希值。

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

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

11
在Python 3中,以下代码将会出错:*** AttributeError: 'bytes' object has no attribute 'encode'。以下代码可以正常运行:import base64; base64.b64encode(h.digest()).decode() - naught101

8

首先,Base64编码会使字符串变长。(以Python3为例,在IPython中演示):

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()就没有意义了。

1
我正在为浏览器的CSP哈希生成内联JavaScript的哈希值,并使用base64编码,因此上述接受的答案会出现以下错误。原因是,没有正确处理所有类型的字符串。

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哈希值的过程。


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