为字典生成唯一标识符?

时间:2017-05-20 19:56:57

标签: python dictionary hash uniqueidentifier

我有一个问题,我随机生成一个字典,可能有很多可能性(比方说,我有25&000; 000可能是不同的dics)。我想为这些可能性中的每一种生成一个标识符,一个ID。我想要的是:

  • 如果两个词典对每个键具有完全相同的值,则ID是相同的
  • 如果两个词典具有不同的ID,则必须在其内容中至少有一个差异。
  • 每次运行程序时,ID都保持不变(id(x)不起作用)
  • 奖励:不同版本的Python(2.6,2.7,3.4,3.6)
  • 的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)

据我所知,这应该适用于大多数情况,但是根据字典和键的实际内容,两个不同的dics产生相同的ID并不是不可能的。例如,如果我没有散列键并且两个不同的条目可以是" 1.0",那么我可能会遇到问题。

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

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

2 个答案:

答案 0 :(得分:1)

依赖运气;其他人都有充分的理由。除非您的ID长于您可以编码的最长字典,或者您选择不能对某些字典进行编码,否则将会有多个具有相同ID的字典。这是一个简单的计算问题。假设您将一个字典命名为1,另外两个字典,依此类推。你最终会用完数字,或者你的ID会变长。 CGenerally我们使用ID或哈希当我们想要一些小的数量,代表一个对象。如果您愿意将字典的名称与字典本身一样大,那么您正在寻找规范表示,而不是ID或哈希。

像p256这样的东西的优点是我们认为很难找到两个具有相同散列的输入。虽然理论上确定有多个输入可以提供相同的sha256,但我们相信没有人发现两个输入可以提供相同的sha256。 所以,你几乎肯定是安全的,忽略了你将遇到哈希冲突的可能性。

答案 1 :(得分:0)

要创建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'