2011-08-03 16 views
11

のチェックサム:Pythonの、私はそれがいることを私は持っている現時点では変更されたりしませ たかどうかを知るために辞書のチェックサムを作成するために考えているのdict

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

はおそらく、よりよい解決策が存在しますか?

注:優れたEtagを作成するための辞書の一意のIDを作成します。

EDIT:私はdictで抽象的なデータを持つことができます。

+0

あなたの辞書には何が入っていますか?それが単なる文字列ならば、ソートされた文字列表現をハッシュすることができます: 'hash(repr(sorted(my_dict.items()))'。 – katrielalex

+0

抽象データとは何ですか? dict-hashアルゴリズムの安定性と作業性は、どのデータを保持するかによって大きく異なります。例えば、あなたが辞書の辞書を持っているならどうしますか? – katrielalex

+0

これらのデータ型は次のとおりです。http://code.google.com/appengine/docs/python/datastore/typesandpropertyclasses.html – sahid

答えて

7

何かにチェックサムを計算します:

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

dictの各(キー、値)タプルのハッシュを取り、それらをすべてXORします。 dictのは非ハッシュの項目が含まれている場合

@katrielalex あなたはこれを行うことができます:

hash(str(d)) 

または多分より良いを

hash(repr(d)) 
+0

これはエレガントです。 –

+0

辞表に解けない項目が含まれているとどうなりますか? – katrielalex

+1

文字列表現に表示される項目の順序が定義されていないため、偽陰性のない 'str(d)'は実行できません。 – katrielalex

1

pickleは、ハッシュが毎回同じ方法でシリアル化されることを保証するかどうか分かりません。

あなただけの辞書を持っている場合、私は、keys()へのコールのOの組み合わせのために行くsorted()、ソート済みキー/値ペアに基づいて文字列を構築し、このようなこと

+0

"" "x、yの場合、.join("%s、%s "%(x、y) (foo.iteritems())) '(ここでfooはdictです)は、ハッシュできる署名として機能します。 –

+0

そして私は私の辞書に抽象データがあるのですか?それは問題じゃない? – sahid

+0

私は、各サブ構造のソートされたデータをシリアル化する再帰関数を実行しなければならないと思います –

0

あなたが言ったように、あなたが辞書に基づいたEtagを生成したいです辞書の順番を保持するOrderedDictがここではより良い候補になるかもしれません。ちょうどイテレータをキー、値のペアを介して、あなたのEtag文字列を構築します。

0

私はあなたがこれに入る微妙なもののいくつかを理解していないかもしれないと思います。最初の問題は、ディクショナリに表示される項目の順序が実装によって定義されていないことです。これは、あなたが

str(d1) == "{'a':1, 'b':2}" 
str(d2) == "{'b':2, 'a':1}" 

を持つことができ、これらは異なる値にハッシュされるため、単に、動作しない辞書のstrを求めていることを意味します。あなたは辞書でのみハッシュ可能アイテムを持っている場合は、それらをハッシュして、そのハッシュをアップに参加することができ、@Bart

hash(tuple(sorted(hash(x) for x in d.items()))) 

をしたり、単純に

よう注意 sorted、あなたはハッシュ化されたタプルがで出てくることを確認する必要がありますので、どんな順序で項目が辞書に現れるかに関係なく同じ順序。あなたが辞書に辞任しているなら、これを繰り返すことができますが、それは複雑になります。

しかし、あなたは、単に壊れ__hash__実装を持つオブジェクトを作成し、それを使用することができますので、あなたが辞書に任意データを許可する場合は、このような任意の実装を破るのは簡単だろう。 idを使用することはできません。なぜなら、異なるアイテムを比較することができるからです。

ストーリーの道徳は、ハッシュディクテーションが理由でPythonでサポートされていないということです。

0

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) 
関連する問題

 関連する問題