我正在考虑创建一个dict的校验和来知道它是否被修改了.目前我有这个:
>>> import hashlib
>>> import pickle
>>> d = {'k': 'v', 'k2': 'v2'}
>>> z = pickle.dumps(d)
>>> hashlib.md5(z).hexdigest()
'8521955ed8c63c554744058c9888dc30'
Run Code Online (Sandbox Code Playgroud)
也许存在更好的解决方案?
注意:我想创建一个独特的dict id来创建一个好的Etag.
编辑:我可以在dict中有抽象数据.
像这样的东西:
reduce(lambda x,y : x^y, [hash(item) for item in d.items()])
Run Code Online (Sandbox Code Playgroud)
获取dict中每个(key,value)元组的哈希值并将它们全部异或.
@katrielalex如果dict包含不可用的项目,你可以这样做:
hash(str(d))
Run Code Online (Sandbox Code Playgroud)
或者甚至更好
hash(repr(d))
Run Code Online (Sandbox Code Playgroud)
在 Python 3 中,哈希函数是用一个随机数初始化的,每个 Python 会话的随机数都不同。如果这对于预期的应用程序来说是不可接受的,请使用例如 zlib.adler32 来构建 dict 的校验和:
import zlib
d={'key1':'value1','key2':'value2'}
checksum=0
for item in d.items():
c1 = 1
for t in item:
c1 = zlib.adler32(bytes(repr(t),'utf-8'), c1)
checksum=checksum ^ c1
print(checksum)
Run Code Online (Sandbox Code Playgroud)
我会推荐一种与您提议的方法非常相似的方法,但有一些额外的保证:
import hashlib, json
hashlib.md5(json.dumps(d, sort_keys=True, ensure_ascii=True).encode('utf-8')).hexdigest()
Run Code Online (Sandbox Code Playgroud)
sort_keys=True
:如果密钥的顺序发生变化,请保留相同的哈希值ensure_ascii=True
:如果您有一些非 ASCII 字符,请确保表示形式不会改变我们将其用于我们的 ETag。