Python,获取图像对象的 base64 编码 MD5 哈希
Python, get base64-encoded MD5 hash of an image object
我需要获取一个对象的 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()
但是,我认为这是不对的,因为它 return 是一个包含太多字符的字符串。我的理解是它需要 24 个字符长。我得到
NjJiM2RlOWMzOTYxYmM3MDI5Y2Q1NzdjOTQ5YWRlYTQ=
我也尝试过其他一些类似的方法,例如,一种不执行块循环的方法。它们都是 return 相同的字符串。
(我后来需要 base64 编码的 MD5 哈希的操作失败了,我想这可能就是原因。)
首先,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()
.
是没有意义的
我能够通过使用 digest() 而不是 hexdigest() 使其工作。那么最后一行变成:
return hash.digest().encode('base64').strip()
结果是 24 个字符长,Google 云存储传输接受了它,这需要 base64 编码的 MD5 哈希。
对于Python 3(来自下面的评论):
import base64;
return base64.b64encode(h.digest()).decode()
我正在为浏览器的 CSP 哈希生成一个带有 base64 编码的内联 javascript 哈希,所以上面接受的答案给出了以下错误。原因是所有类型的字符串都没有处理好
AttributeError: 'bytes' object has no attribute '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 哈希。
我需要获取一个对象的 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()
但是,我认为这是不对的,因为它 return 是一个包含太多字符的字符串。我的理解是它需要 24 个字符长。我得到
NjJiM2RlOWMzOTYxYmM3MDI5Y2Q1NzdjOTQ5YWRlYTQ=
我也尝试过其他一些类似的方法,例如,一种不执行块循环的方法。它们都是 return 相同的字符串。
(我后来需要 base64 编码的 MD5 哈希的操作失败了,我想这可能就是原因。)
首先,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()
.
我能够通过使用 digest() 而不是 hexdigest() 使其工作。那么最后一行变成:
return hash.digest().encode('base64').strip()
结果是 24 个字符长,Google 云存储传输接受了它,这需要 base64 编码的 MD5 哈希。
对于Python 3(来自下面的评论):
import base64;
return base64.b64encode(h.digest()).decode()
我正在为浏览器的 CSP 哈希生成一个带有 base64 编码的内联 javascript 哈希,所以上面接受的答案给出了以下错误。原因是所有类型的字符串都没有处理好
AttributeError: 'bytes' object has no attribute '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 哈希。