2010-01-20 6 views
17

मैं हैश गुणवत्ता और हैश स्थिरता के बारे में सोच रहा हूं String.GetHashCode() .NET में कार्यान्वयन द्वारा उत्पादित?स्ट्रिंग.गेटहाशकोड() में हैश की गुणवत्ता और स्थिरता हैट में?

गुणवत्ता के बारे में, मैं एल्गोरिदमिक पहलुओं पर ध्यान केंद्रित कर रहा हूं (इसलिए, हैश की गुणवत्ता क्योंकि यह बड़ी हैश-टेबल को प्रभावित करती है, सुरक्षा चिंताओं के लिए नहीं)।

फिर, स्थिरता से संबंधित, मैं संभावित संस्करण समस्याओं के बारे में सोच रहा हूं जो एक .NET संस्करण से अगले तक उत्पन्न हो सकते हैं।

उन दो पहलुओं पर कुछ रोशनी की बहुत सराहना की जाएगी।

उत्तर

19

मैं आपको गुणवत्ता के बारे में कोई विवरण नहीं दे सकता (हालांकि मुझे लगता है कि यह बहुत अच्छा है कि स्ट्रिंग ढांचे के मुख्य वर्गों में से एक है जिसे हैश कुंजी के रूप में उपयोग करने की संभावना है)।

हालांकि, स्थिरता के संबंध में, ढांचे के विभिन्न संस्करणों पर उत्पादित हैश कोड समान होने की गारंटी नहीं है, और यह अतीत में बदल गया है, इसलिए आपको संस्करणों के बीच स्थिर हैश कोड पर भरोसा नहीं करना चाहिए (see here for a reference that it changed between 1.1 and 2.0)। वास्तव में, यह के समान फ्रेमवर्क संस्करण के 32-बिट और 64-बिट संस्करणों के बीच भी भिन्न है; from the docs:

गेटहाशकोड द्वारा लौटाया गया मूल्य प्लेटफ़ॉर्म-निर्भर है। एक विशिष्ट स्ट्रिंग मान के लिए, यह .NET Framework के 32-बिट और 64-बिट संस्करणों पर भिन्न होता है।

0

हैश कोड की गुणवत्ता उनके इच्छित उद्देश्य के लिए पर्याप्त है, यानी जब आप एक शब्दकोश में तार के रूप में तारों का उपयोग करते हैं तो वे बहुत से टकराव नहीं करते हैं। मुझे संदेह है कि हैश कोड की गणना करने के लिए यह केवल संपूर्ण स्ट्रिंग का उपयोग करेगा यदि स्ट्रिंग लम्बाई काफी कम है, तो बड़े तारों के लिए यह केवल पहले भाग का उपयोग करेगा।

संस्करणों में स्थिरता की कोई गारंटी नहीं है। दस्तावेज स्पष्ट रूप से कहता है कि हैशिंग एल्गोरिदम एक संस्करण से दूसरे संस्करण में बदल सकता है, ताकि हैश कोड अल्पकालिक उपयोग के लिए हैं।

2

मैं अभी इस से संबंधित समस्या में आया हूं। मेरे कंप्यूटरों में से एक (64 बिट एक) में मुझे एक समस्या थी जिसे मैंने (संग्रहित) हैशकोड को छोड़कर 2 अलग-अलग ऑब्जेक्ट्स को समान रूप से ट्रैक किया था। वह हैशकोड एक स्ट्रिंग से बनाया गया था .... एक ही स्ट्रिंग!

m_storedhash = astring.GetHashCode();

मुझे पता है कि कैसे इन दो वस्तुओं को देखते हुए वे एक ही स्ट्रिंग लेकिन मुझे लगता है कि क्या हुआ से कर दिया जाता था हैश कोड के साथ समाप्त हो गया न है कि एक ही नेट exe, वर्ग पुस्तकालय परियोजनाओं में से एक के भीतर मैं पर निर्भर करता है कि x86 और दूसरे को ANYCPU पर सेट किया गया है और इनमें से एक ऑब्जेक्ट x86 क्लास lib के अंदर एक विधि में बनाया गया था और अन्य ऑब्जेक्ट (समान इनपुट डेटा, वही सब कुछ) ANYCPU क्लास लाइब्रेरी के अंदर एक विधि में बनाया गया था।

तो, क्या यह ध्वनि व्यावहारिक है: स्मृति में समान निष्पादन योग्य (प्रक्रियाओं के बीच नहीं) कुछ कोड x86 फ्रेमवर्क की स्ट्रिंग के साथ चल रहे थे। गेटहाशकोड() और अन्य कोड x64 फ्रेमवर्क की स्ट्रिंग। गेटहाशकोड()?

2

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

https://connect.microsoft.com/VisualStudio/feedback/details/517457/stringcomparers-gethashcode-string-throws-outofmemoryexception-with-plenty-of-ram-available

13

यह एक पुरानी सवाल है, लेकिन मैं this microsoft bug about hash quality mentionning द्वारा योगदान करना चाहते हैं।

सारांश: 64 बी पर, हैश गुणवत्ता बहुत कम है जब आपकी स्ट्रिंग में '0 0 बाइट है। असल में, केवल स्ट्रिंग की शुरुआत ही हो जाएगी।

यदि मुझे पसंद है, तो आपको उच्च प्रदर्शन वाले शब्दकोशों के लिए बाइनरी डेटा का प्रतिनिधित्व करने के लिए नेट स्ट्रिंग का उपयोग करना होगा, आपको इस बग से अवगत होना चाहिए।

बहुत खराब है, यह एक WONTFIX है ... एक sidenote के रूप, मुझे समझ नहीं आता कि वे कैसे कह सकते हैं एक को तोड़ने परिवर्तन, जब कोड

// We want to ensure we can change our hash function daily. 
// This is perfectly fine as long as you don't persist the 
// value from GetHashCode to disk or count on String A 
// hashing before string B. Those are bugs in your code. 
hash1 ^= ThisAssembly.DailyBuildNumber; 

शामिल किया जा रहा है hashCode को संशोधित करने और hashCode है कि वैसे भी x86/64b में पहले से ही अलग है।

संबंधित मुद्दे