2011-08-03 13 views
11

मैं या जानना चाहते हैं कि यह संशोधित किया गया था एक dict की चेकसम बनाने के लिए सोच रहा हूँ नहीं पल मैं उस राशि के लिए की चेकसम:अजगर, एक dict

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

शायद एक बेहतर समाधान मौजूद है?

नोट: मैं एक अच्छा इटाग बनाने के लिए एक निर्देश की एक अद्वितीय आईडी बनाना चाहता हूं।

संपादित करें: मेरे पास dict में सार डेटा हो सकता है।

+0

अपने dict में क्या है? अगर यह सिर्फ तार है (कहें) तो आप बस क्रमबद्ध स्ट्रिंग का प्रतिनिधित्व कर सकते हैं: 'हैश (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()]) 

निर्देश में प्रत्येक (कुंजी, मूल्य) टुपल का हैश और उन्हें पूरी तरह से एक्सओआर लें।

@katrielalex dict unhashable आइटम शामिल हैं आप ऐसा कर सकता है:

hash(str(d)) 

या हो सकता है और भी बेहतर

hash(repr(d)) 
+0

के आधार पर क्रमबद्ध है। यह सुरुचिपूर्ण है। –

+0

क्या होगा यदि ताना में अनावश्यक वस्तुएं हों? – katrielalex

+1

आप झूठी नकारात्मकताओं के बिना 'str (d)' नहीं कर सकते हैं, क्योंकि जिस क्रम में स्ट्रिंग प्रस्तुति में आइटम प्रकट होते हैं, वह अनिर्धारित है। – katrielalex

1

मुझे नहीं पता कि pickle आपको गारंटी देता है कि हैश हर बार उसी तरह से क्रमबद्ध है।

आप केवल शब्दकोशों है, तो मैं keys(), sorted() के लिए कॉल के ओ संयोजन के लिए जाना होगा, क्रमबद्ध कुंजी/मान जोड़े के आधार पर एक स्ट्रिंग का निर्माण और उस

+0

'" "। जॉइन ("% s,% s "% (x, y) x, y के लिए क्रमबद्ध (foo.iteritems())) '(जहां foo dict है) एक हस्ताक्षर के रूप में काम कर सकता है जिसे आप हैश कर सकते हैं। –

+0

और मेरे बारे में क्या है यदि मेरे पास मेरे निर्देश में अमूर्त डेटा है? वह कोई समस्या नहीं है? – sahid

+0

मुझे लगता है कि आपको एक रिकर्सिव फ़ंक्शन करना होगा जो प्रत्येक उप संरचना –

0

जैसा कि आपने कहा, आप शब्दकोश के आधार पर एक ETag उत्पन्न करने के लिए चाहता था सामग्री, OrderedDict जो शब्दकोश का क्रम सुरक्षित रखता है यहां बेहतर उम्मीदवार हो सकता है। कुंजी, मूल्य जोड़े के माध्यम से बस इटेटरेटर और अपनी Etag स्ट्रिंग का निर्माण।

0

मुझे लगता है कि आप इसमें शामिल कुछ सूक्ष्मताओं का एहसास नहीं कर सकते हैं। पहली समस्या यह है कि एक आदेश में वस्तुओं को प्रकट करने का आदेश कार्यान्वयन द्वारा परिभाषित नहीं किया जाता है। इसका मतलब है कि बस एक dict काम नहीं करता है की str के लिए पूछ रहा है, क्योंकि आप

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

हो सकता था और इन विभिन्न मूल्यों के हैश होगा। आप dict में केवल hashable आइटम नहीं हैं, तो आप उन्हें हैश सकते हैं और फिर अपने हैश शामिल, @Bart करता है या बस

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

नोट sorted के रूप में है, क्योंकि आप यह सुनिश्चित करें कि टुकड़ों में बंटी टपल में बाहर आता है उसी क्रम के बावजूद वस्तुओं को आदेश में कौन सा आदेश दिखाई देता है। यदि आपके पास तानाशाही में डिक्ट्स हैं, तो आप इसे पुनः प्राप्त कर सकते हैं, लेकिन यह जटिल होगा।

लेकिन यह इस तरह किसी भी कार्यान्वयन को तोड़ने के लिए यदि आप शब्दकोश में मनमाना डेटा की अनुमति के लिए आसान हो सकता है के बाद से आप बस एक टूटी हुई __hash__ कार्यान्वयन के साथ एक वस्तु लिख सकते हैं और है कि का उपयोग कर सकते हैं। और आप id का उपयोग नहीं कर सकते हैं, क्योंकि तब आपके पास समान आइटम हो सकते हैं जो अलग-अलग तुलना करते हैं।

कहानी का नैतिक यह है कि एक कारण के लिए पाइथन में हैशिंग डाइट्स समर्थित नहीं है।

0

पायथन 3 में, हैश फ़ंक्शन को यादृच्छिक संख्या के साथ प्रारंभ किया गया है, जो प्रत्येक पायथन सत्र के लिए अलग है। यदि वह इच्छित एप्लिकेशन के लिए स्वीकार्य नहीं है, तो उदा। 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) 
संबंधित मुद्दे