मुझे एक हैश फ़ंक्शन चाहिए जो लंबी संख्या (64 बिट्स) लेता है और 10 बिट्स का परिणाम उत्पन्न करता है। इस उद्देश्य के लिए सबसे अच्छा हैश फ़ंक्शन क्या है। इनपुट मूल रूप से चर के पते हैं (पते 64 बिट्स या लिनक्स पर 8 बाइट्स हैं), इसलिए मेरे उद्देश्य फ़ंक्शन को उस उद्देश्य के लिए अनुकूलित किया जाना चाहिए।64 बिट से 10 बिट्स के लिए हैश फ़ंक्शन
उत्तर
मैं इस तरह somethig कहेंगे:
uint32_t hash(uint64_t x)
{
x >>= 3;
return (x^(x>>10)^(x>>20)) & 0x3FF;
}
ऐसा न हो कि महत्वपूर्ण 3 बिट्स के रूप में सबसे चर 4 बाइट या 8-बाइट गठबंधन कर रहे हैं, बहुत ही उपयोगी नहीं हैं, इसलिए हम उन्हें निकाल देते। फिर हम अगले 30 बिट्स लेते हैं और 10 बिट्स के ब्लॉक में उन्हें एक साथ (एक्सओआर) मिलाते हैं।
स्वाभाविक रूप से, आप (x>>30)^(x>>40)^(x>>50)
भी ले सकते हैं लेकिन मुझे यकीन नहीं है कि वे अभ्यास में कोई फर्क नहीं पड़ेगा।
चूंकि आप मिश्रण के लिए xor-shift का उपयोग करते हैं, इसलिए मैं मर्सग्लिया द्वारा वर्णित उनके 64x64 मैट्रिक्स में 2^64-1 अवधि के साथ ज्ञात 275 ट्रिपलेट्स का उपयोग करने की अनुशंसा करता हूं, उदाहरण के लिए (7,11,10) या (21, 17,48)। चूंकि यह छद्म यादृच्छिक तरीके से किसी भी ज्ञात विषमता के साथ बिट्स को मिश्रित करता है, इसलिए यह 0x3ff करने से पहले सभी शब्दों को एक साथ जोड़ना मान्य है। इस तरह, प्रत्येक इनपुट बिट में सभी आउटपुट बिट्स को प्रभावित करने का मौका होना चाहिए। शायद क्रिप्टोग्राफिक हैश में पूरी तरह से 50:50 वितरित नहीं किया गया है, लेकिन जैसा कि आप प्राप्त कर सकते हैं उतना अच्छा है। इसके अलावा, अभी भी एक उत्कृष्ट विचार, +1 – Damon
अधिकांश वितरण के लिए सर्वश्रेष्ठ एक प्राइम द्वारा संशोधित है, 1021 सबसे बड़ा 10-बिट प्राइम है। कम बिट्स को पट्टी करने की कोई ज़रूरत नहीं है।
static inline int hashaddress(void *v)
{
return (uintptr_t)v % 1021;
}
अगर आपको लगता है प्रदर्शन चिंता का विषय हो सकता है, हाथ पर कुछ विकल्पों की है और अपने वास्तविक कार्यक्रम में उन्हें दौड़। Microbenchmarks बर्बाद कर रहे हैं; कुछ चक्रों का अंतर कैश प्रभावों और आकार के मामलों से घिरा हुआ लगभग निश्चित है।
मैंने लिखा एक खिलौना कार्यक्रमके ढेर, डेटा क्षेत्र है, और ढेर पर कुछ वास्तविक पते को देखने। असल में मैंने 4 ग्लोबल्स, 4 स्थानीय लोगों की घोषणा की और 2 mallocs
किया। पते को प्रिंट करते समय मैंने पिछले दो बिट्स को गिरा दिया।
20125e8
20125e6
20125e7
20125e4
3fef2131
3fef2130
3fef212f
3fef212c
25e4802
25e4806
क्या यह मुझसे कहता है:: यहाँ रन में से एक से एक उत्पादन होता है
- LSB इस निर्गम (पते के 3 बिट) अक्सर 'चालू' है में और 'ऑफ'। तो हैश की गणना करते समय मैं इसे छोड़ नहीं दूँगा। 2 एलएसबी छोड़ना पर्याप्त लगता है।
- हम यह भी देखते हैं कि निचले 8-10 बिट्स में अधिक एन्ट्रॉपी है। हमें का उपयोग करना चाहिए कि हैश की गणना करते समय।
- हम जानते हैं कि 64 बिट मशीन पर, virtual addresses are never more than 48 bits wide।
मैं अगले करना होगा क्या:
/* Drop two LSBs. */
a >>= 2;
/* Get rid of the MSBs. Keep 46 bits. */
a &= 0x3fffffffffff;
/* Get the 14 MSBs and fold them in to get a 32 bit integer.
The MSBs are mostly 0s anyway, so we don't lose much entropy. */
msbs = (a >> 32) << 18;
a ^= msbs;
अब हम एक decent 'half avalanche' hash function के माध्यम से इस गुजरती हैं, बजाय हमारे अपने रोलिंग की ।
uint32_t half_avalanche(uint32_t a)
{
a = (a+0x479ab41d) + (a<<8);
a = (a^0xe4aa10ce)^(a>>5);
a = (a+0x9942f0a6) - (a<<14);
a = (a^0x5aedd67d)^(a>>3);
a = (a+0x17bea992) + (a<<7);
return a;
}
एक 10 बिट हैश के लिए, uint32_t
लौटे 10 MSBs का उपयोग करें: 'आधा हिमस्खलन' इनपुट के प्रत्येक बिट एक ही स्थान पर बिट्स प्रभावित करने के लिए और मौका उच्च हो जाता है का मतलब है।हैश फ़ंक्शन ठीक काम करता रहता है यदि आप N
N
बिट हैश के लिए एमएसबी चुनते हैं, जो प्रत्येक अतिरिक्त बिट के साथ बाल्टी गिनती को प्रभावी ढंग से दोगुना करते हैं।
मैं थोड़ा ऊब गया था, इसलिए मैंने इसके लिए एक खिलौना बेंचमार्क लिखा। कुछ भी फैंसी नहीं है, यह ढेर पर स्मृति का एक गुच्छा आवंटित करता है और ऊपर वर्णित हैश की कोशिश करता है। स्रोत here से हो सकता है। एक उदाहरण परिणाम:
1024 बाल्टी, 256 मूल्यों उत्पन्न, 29 collissions
1024 बाल्टी, 512 मूल्यों उत्पन्न, 103 collissions
1024 बाल्टी, 1024 मान उत्पन्न, 370 collissions
अगला: मैंने अन्य दो हैशों का उत्तर यहां दिया। दोनों के पास समान प्रदर्शन है। ऐसा लगता है: बस सबसे तेज़ चुनें;)
- 1. ubuntu 10 64 बिट
- 2. एएसपी.नेट एमवीसी 3.0 बिल्ड बिट्स 64 बिट
- 3. जावा जेडीके 32 बिट्स बनाम 64 बिट्स
- 4. विंडोज 7 64 बिट बिट्स बिट्स 32 बिट्स लाइब्रेरी 32 बिट्स के लिए लाइब्रेरी लोड करते समय
- 5. विंडोज 7 64 बिट्स
- 6. विंडोज विस्टा 64 बिट्स
- 7. 64 बिट सिस्टम में, 32 बिट कॉलम 64 बिट एक से कम स्थान पर है?
- 8. लिनक्स पर QtCreator: 32-बिट्स बनाम 64-बिट्स
- 9. फ़ंक्शन हैश से फिस हैश स्लाइस फ़ंक्शन
- 10. 16 बिट्स बिट गहराई
- 11. 64-बिट विंडोज़
- 12. 64 बिट्स पर चल रहे 32 बिट्स ग्रहण JVM
- 13. 64-बिट विंडोज असेंबलर
- 14. 64-बिट लिनक्स सर्वर पर 64-बिट जेवीएम चलाने के लिए लाभ/कमी?
- 15. एक आईडी के रूप में sha1 हैश के केवल 64-बिट्स का उपयोग करने के लिए ठीक है?
- 16. 64-बिट
- 17. 64-बिट सी ++
- 18. 64 या 64 बिट वर्चुअल मशीन 64 बिट मशीन (vmware)
- 19. जावास्क्रिप्ट 64 बिट संख्यात्मक परिशुद्धता
- 20. 64-बिट
- 21. 64 बिट्स में Fsi.exe को कैसे चलाएं?
- 22. सी ++ युगल सुनिश्चित करना 64 बिट्स
- 23. 64-बिट जावा ऐप्स: क्या 64-बिट ओएस, 64-बिट जेआरई और 64-बिट एप्लिकेशन आवश्यक है?
- 24. अजीब ASP.NET AJAX बग/32-बिट 64-बिट के लिए
- 25. 64 बिट बनाम विंडोज फोन विकास के लिए 32 बिट
- 26. संकलित ASP.NET 64 बिट के लिए
- 27. 64 बिट के लिए जावा प्रोग्रामिंग JVM
- 28. 32 बिट बनाम 64 बिट
- 29. 64 बिट अनुप्रयोग में 32 बिट डीएलएल लाइब्रेरी लोड करें
- 30. 32 बिट हैश
आपके ब्रह्मांड में 64-बिट मानों के वितरण के बारे में कौन सी जानकारी आपको दे सकती है? –
सभी मामलों के लिए कोई "सर्वश्रेष्ठ" हैश फ़ंक्शन नहीं है। आपको अपने इनपुट नंबरों के वितरण और लक्षणों का अध्ययन करना होगा। –
इनपुट लिनक्स पर चर के पते है। – MetallicPriest