为字典生成唯一标识符?

Generate unique identifier for dictionary?

我有一个问题,我随机生成一个字典,可能有很多可能性(比如,我有 25'000 个可能不同的字典)。我想为每一种可能性生成一个标识符,一个 ID。我想要的是:

我目前的想法是使用哈希函数(虽然我对此知之甚少)并做这样的事情(假设一个 int/float 数字的字典):

import hashlib
def getID(mydic):
    ID = 0
    for x in mydic.keys():
        # Hash the content
        ID = ID + int(hashlib.sha256(str(mydic[x]).encode('utf-8')).hexdigest(), 16)
        # Hash the key
        ID = ID + int(hashlib.sha256(x.encode('utf-8')).hexdigest(), 16)
    return (ID % 10**10)

根据我的理解,这在大多数情况下应该有效,但根据字典和键的实际内容,两个不同的 dic 产生相同的 ID 并非不可能。例如,如果我不对密钥进行哈希处理,并且两个不同的条目可以是“1.0”,那么我就会遇到问题。

你有什么建议,希望不要靠运气吗?

编辑:我在我想做的事情上添加了一个更大的代码:它基本上是一个随机参数优化。 Code on pastebin

要创建 ID,您需要创建一个不可变对象。 由于键是无序的,您可能需要对它们进行排序。

例如:

mydict = {'a': 1, 'c': 9, 'b': 3}

values = tuple(sorted(mydict.items()))
# -> (('a', 1), ('b', 3), ('c', 9))

然后,您可以使用自己的哈希算法,例如使用 sha256:

import hashlib

def hash_item(m, k, v):
    m.update(k.encode('utf-8'))
    m.update(str(k).encode('utf-8'))

m = hashlib.sha256()
for k, v in values:
    hash_item(m, k, v)
print(m.digest())
# -> b'\xa5\xb42\xee\x03\x07\xbe\x7f\xa2:\xa0\x04a\xf5N\xee4\xba\x9dE%\x1bU\x04V}7\xa8\xda3\x9d\xff'

靠运气;每个人都有充分的理由这样做。除非你的ID比你能编码的最长字典还长,或者你选择不能对某些字典进行编码,那么就会出现多个具有相同ID的字典。这是一个简单的计数问题。假设您将一本字典命名为 1,将另外两本命名为 1,依此类推。要么你最终 运行 没有号码,要么你的 ID 变长了。 C通常,当我们想要一些代表对象的少量数据时,我们会使用 ID 或哈希。如果您愿意让字典的名称与字典本身一样大,那么您正在寻找规范表示,而不是 ID 或哈希。

sha256 之类的优点是我们认为很难找到具有相同哈希值的两个输入。尽管理论上可以肯定有多个输入给出相同的 sha256,但我们认为还没有人发现两个输入给出相同的 sha256。 所以,你几乎可以肯定足够安全,忽略你 运行 跨越哈希冲突的可能性。