Python,字典的校验和

17 投票
6 回答
9749 浏览
提问于 2025-04-16 22:47

我在考虑给一个字典(dict)创建一个校验和,这样我就能知道它是否被修改过。

>>> import hashlib
>>> import pickle
>>> d = {'k': 'v', 'k2': 'v2'}
>>> z = pickle.dumps(d)
>>> hashlib.md5(z).hexdigest()
'8521955ed8c63c554744058c9888dc30'

也许还有更好的解决方案?

注意:我想为这个字典创建一个唯一的ID,以便生成一个好的Etag。

编辑:这个字典里可能包含一些抽象的数据。

6 个回答

8

我建议一种和你提到的方式很相似,但加了一些额外的保证:

import hashlib, json
hashlib.md5(json.dumps(d, sort_keys=True, ensure_ascii=True).encode('utf-8')).hexdigest()
  • sort_keys=True:如果你的键的顺序改变,哈希值保持不变
  • ensure_ascii=True:如果你有一些非ASCII字符,这样可以确保表示方式不变

我们在我们的ETag中使用这个。

8

在Python 3中,哈希函数是用一个随机数来初始化的,这个随机数在每次Python会话中都是不同的。如果这样的做法不适合你的应用需求,可以使用比如zlib.adler32来为字典生成校验和:

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)
10

像这样:

reduce(lambda x,y : x^y, [hash(item) for item in d.items()])

对字典中的每一对(键,值)进行哈希处理,然后把它们全部进行异或运算。

@katrielalex 如果字典里有不能哈希的项目,你可以这样做:

hash(str(d))

或者可能更好的是

hash(repr(d))

撰写回答