कौन सी हैशिंग एल्गोरिथ्म विशिष्टता और गति के लिए सबसे अच्छा है?


1388

कौन सी हैशिंग एल्गोरिथ्म विशिष्टता और गति के लिए सबसे अच्छा है? उदाहरण (अच्छे) उपयोगों में हैश शब्दकोश शामिल हैं।

मुझे पता है कि SHA-256 और इस तरह की चीजें हैं , लेकिन इन एल्गोरिदम को सुरक्षित बनाने के लिए डिज़ाइन किया गया है , जिसका अर्थ है कि वे एल्गोरिदम की तुलना में धीमी हैं जो कम अद्वितीय हैं । मैं चाहता हूं कि एक हैश एल्गोरिथ्म तेजी से तैयार किया जाए, फिर भी टकराव से बचने के लिए काफी अद्वितीय बने रहें।


9
किस उद्देश्य, सुरक्षा या अन्य के लिए?
परिक्रमा

19
@ हैल्लिंग, हैश शब्दकोश के कार्यान्वयन के लिए। इसलिए टकरावों को कम से कम रखा जाना चाहिए, लेकिन इसका कोई सुरक्षा उद्देश्य नहीं है।
अर्लज़

4
ध्यान दें कि आपको अपने हैश तालिका में कम से कम कुछ टकरावों की उम्मीद करनी होगी , अन्यथा तालिका को अपेक्षाकृत कम संख्या में कुंजियों को संभालने में सक्षम होने की आवश्यकता होगी ...
डीन हार्डिंग

19
महान पद! क्या आप Yann Collet का xxHash (निर्माता या LZ4) भी देख सकते हैं, जो मुरमुर से दोगुना है? होमपेज: code.google.com/p/xxhash : अधिक जानकारी fastcompression.blogspot.fr/2012/04/...

24
@zvrba एल्गोरिथ्म पर निर्भर करता है। bcrypt को धीमा बनाने के लिए डिज़ाइन किया गया है।
इजाकाता

जवाबों:


2461

मैंने कुछ अलग एल्गोरिदम का परीक्षण किया, गति और टकराव की संख्या को मापा।

मैंने तीन अलग-अलग कुंजी सेटों का उपयोग किया:

प्रत्येक कॉर्पस के लिए, हैशिंग और औसत समय बिताया हैशिंग की संख्या दर्ज की गई थी।

मैंने परीक्षण किया:

परिणाम

प्रत्येक परिणाम में औसत हैश समय और टकराव की संख्या होती है

Hash           Lowercase      Random UUID  Numbers
=============  =============  ===========  ==============
Murmur            145 ns      259 ns          92 ns
                    6 collis    5 collis       0 collis
FNV-1a            152 ns      504 ns          86 ns
                    4 collis    4 collis       0 collis
FNV-1             184 ns      730 ns          92 ns
                    1 collis    5 collis       0 collis▪
DBJ2a             158 ns      443 ns          91 ns
                    5 collis    6 collis       0 collis▪▪▪
DJB2              156 ns      437 ns          93 ns
                    7 collis    6 collis       0 collis▪▪▪
SDBM              148 ns      484 ns          90 ns
                    4 collis    6 collis       0 collis**
SuperFastHash     164 ns      344 ns         118 ns
                   85 collis    4 collis   18742 collis
CRC32             250 ns      946 ns         130 ns
                    2 collis    0 collis       0 collis
LoseLose          338 ns        -             -
               215178 collis

नोट :

क्या टकराव वास्तव में होता है?

हाँ। मैंने यह देखने के लिए अपने परीक्षण कार्यक्रम लिखना शुरू कर दिया कि क्या हैश टक्कर वास्तव में होती है - और सिर्फ एक सैद्धांतिक निर्माण नहीं है। वे वास्तव में होते हैं:

FNV-1 टकराव

  • creamwove साथ टकराता है quists

FNV-1a टकराव

  • costarring साथ टकराता है liquid
  • declinate साथ टकराता है macallums
  • altarage साथ टकराता है zinke
  • altarages साथ टकराता है zinkes

मुरमुर 2 टकराव

  • cataract साथ टकराता है periti
  • roquette साथ टकराता है skivie
  • shawl साथ टकराता है stormbound
  • dowlases साथ टकराता है tramontane
  • cricketings साथ टकराता है twanger
  • longans साथ टकराता है whigs

डीजेबी 2 टक्कर

  • hetairas साथ टकराता है mentioner
  • heliotropes साथ टकराता है neurospora
  • depravement साथ टकराता है serafins
  • stylist साथ टकराता है subgenera
  • joyful साथ टकराता है synaphea
  • redescribed साथ टकराता है urites
  • dram साथ टकराता है vivency

डीजेबी 2 ए की टक्कर

  • haggadot साथ टकराता है loathsomenesses
  • adorablenesses साथ टकराता है rentability
  • playwright साथ टकराता है snush
  • playwrighting साथ टकराता है snushing
  • treponematoses साथ टकराता है waterbeds

CRC32 टक्कर

  • codding साथ टकराता है gnu
  • exhibiters साथ टकराता है schlager

SuperFastHash टकराव

  • dahabiah साथ टकराता है drapability
  • encharm साथ टकराता है enclave
  • grahams साथ टकराता है gramary
  • ... स्निप 79 टकराव ...
  • night साथ टकराता है vigil
  • nights साथ टकराता है vigils
  • finks साथ टकराता है vinic

Randomnessification

अन्य व्यक्तिपरक उपाय है कि कैसे बेतरतीब ढंग से वितरित किया गया हैश हैं। परिणामी हैशटेबल्स को मैप करने से पता चलता है कि डेटा को समान रूप से कैसे वितरित किया जाता है। सभी हैश फ़ंक्शन तालिका को मैप करते समय अच्छे वितरण को दर्शाते हैं:

यहां छवि विवरण दर्ज करें

या हिल्बर्ट मैप के रूप में ( XKCD हमेशा प्रासंगिक होता है ):

यहां छवि विवरण दर्ज करें

सिवाय जब हैशिंग संख्या के तार ( "1",, "2"... "216553") , (उदाहरण के लिए, ज़िप कोड ), जहां अधिकांश हैशिंग एल्गोरिदम में पैटर्न उभरने लगते हैं:

SDBM :

यहां छवि विवरण दर्ज करें

डीजेबी 2 :

यहां छवि विवरण दर्ज करें

एफएनवी -1 :

यहां छवि विवरण दर्ज करें

एफएनवी -1 ए को छोड़कर सभी , जो अभी भी मेरे लिए बहुत यादृच्छिक हैं:

यहां छवि विवरण दर्ज करें

वास्तव में, Murmur2 कीNumbers तुलना में बेहतर यादृच्छिकता है FNV-1a:

यहां छवि विवरण दर्ज करें

जब मैं FNV-1a"संख्या" मानचित्र को देखता हूं , तो मुझे लगता है कि मैं सूक्ष्म ऊर्ध्वाधर पैटर्न देखता हूं। मुरमुर के साथ मुझे कोई पैटर्न नहीं दिखता है। तुम क्या सोचते हो?


*तालिका में अतिरिक्त यह दर्शाता है कि यादृच्छिकता कितनी खराब है। FNV-1aसबसे अच्छा होने के साथ , और DJB2xसबसे खराब होने के साथ:

      Murmur2: .
       FNV-1a: .
        FNV-1: ▪
         DJB2: ▪▪
        DJB2a: ▪▪
         SDBM: ▪▪▪
SuperFastHash: .
          CRC: ▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪
     Loselose: ▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪
                                        ▪
                                 ▪▪▪▪▪▪▪▪▪▪▪▪▪
                        ▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪
          ▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪▪

मैंने मूल रूप से इस कार्यक्रम को यह तय करने के लिए लिखा था कि क्या मुझे टकराव के बारे में भी चिंता करना चाहिए: मैं करता हूं।

और फिर यह सुनिश्चित करने में बदल गया कि हैश फ़ंक्शन पर्याप्त रूप से यादृच्छिक थे।

FNV-1a एल्गोरिथ्म

FNV1 हैश 32 वेरिएंट में आता है जो 32, 64, 128, 256, 512 और 1024 बिट हैश को लौटाता है।

FNV-1a एल्गोरिथ्म है:

hash = FNV_offset_basis
for each octetOfData to be hashed
    hash = hash xor octetOfData
    hash = hash * FNV_prime
return hash

जहां स्थिरांक FNV_offset_basisऔर FNV_primeआप चाहते हैं कि वापसी हैश आकार पर निर्भर करते हैं:

Hash Size  
===========
32-bit
    prime: 2^24 + 2^8 + 0x93 = 16777619
    offset: 2166136261
64-bit
    prime: 2^40 + 2^8 + 0xb3 = 1099511628211
    offset: 14695981039346656037
128-bit
    prime: 2^88 + 2^8 + 0x3b = 309485009821345068724781371
    offset: 144066263297769815596495629667062367629
256-bit
    prime: 2^168 + 2^8 + 0x63 = 374144419156711147060143317175368453031918731002211
    offset: 100029257958052580907070968620625704837092796014241193945225284501741471925557
512-bit
    prime: 2^344 + 2^8 + 0x57 = 35835915874844867368919076489095108449946327955754392558399825615420669938882575126094039892345713852759
    offset: 9659303129496669498009435400716310466090418745672637896108374329434462657994582932197716438449813051892206539805784495328239340083876191928701583869517785
1024-bit
    prime: 2^680 + 2^8 + 0x8d = 5016456510113118655434598811035278955030765345404790744303017523831112055108147451509157692220295382716162651878526895249385292291816524375083746691371804094271873160484737966720260389217684476157468082573
    offset: 1419779506494762106872207064140321832088062279544193396087847491461758272325229673230371772250864096521202355549365628174669108571814760471015076148029755969804077320157692458563003215304957150157403644460363550505412711285966361610267868082893823963790439336411086884584107735010676915

देखें मुख्य FNV पेज जानकारी के लिए।

मेरे सभी परिणाम 32-बिट संस्करण के साथ हैं।

FNV-1a, FNV-1a से बेहतर है?

एफएनवी -1 ए सभी के आसपास बेहतर है। अंग्रेजी शब्द कॉर्पस का उपयोग करते समय FNV-1a के साथ अधिक टकराव थे:

Hash    Word Collisions
======  ===============
FNV-1   1
FNV-1a  4

अब लोअरकेस और अपरकेस की तुलना करें:

Hash    lowercase word Collisions  UPPERCASE word collisions
======  =========================  =========================
FNV-1   1                          9
FNV-1a  4                          11

इस मामले में FNV-1a FN-1 से "400%" बदतर नहीं है, केवल 20% बदतर है।

मुझे लगता है कि अधिक महत्वपूर्ण बात यह है कि जब टकराव की बात आती है तो एल्गोरिदम के दो वर्ग होते हैं:

  • टकराव दुर्लभ : FNV-1, FNV-1a, DJB2, DJB2a, SDBM
  • टकराव आम : SuperFastHash, Loselose

और फिर वहाँ है कि कैसे समान रूप से वितरित हैश हैं:

  • बकाया वितरण: मुरमुर 2, एफएनवी -1 ए, सुपरफास्ट
  • उत्कृष्ट वितरण: FNV-1
  • अच्छा वितरण: एसडीबीएम, डीजेबी 2, डीजेबी 2 ए
  • भयानक वितरण: लोसलोस

अपडेट करें

बड़बड़ाहट? जरूर, क्यों नहीं


अपडेट करें

@whatshisname ने सोचा कि CRC32 कैसे प्रदर्शन करेगा, अंक तालिका में जोड़े गए।

CRC32 बहुत अच्छा है । कुछ टकराव, लेकिन धीमी, और 1k लुकअप टेबल का ओवरहेड।

सीआरसी वितरण के बारे में सभी गलत सामानों को स्निप करें - मेरा बुरा


आज तक मैं FNV-1a का उपयोग अपने डे वास्तव -हैश-टेबल हैशिंग एल्गोरिथ्म के रूप में करने जा रहा था । लेकिन अब मैं Murmur2 पर स्विच कर रहा हूं:

  • और तेज
  • इनपुट के सभी वर्गों का बेहतर यादृच्छिकता

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

अपडेट: से गूगल पर MurmurHash3 होमपेज :

(1) - सुपरफास्ट हाश में बहुत खराब टक्कर वाले गुण होते हैं, जिन्हें कहीं और प्रलेखित किया गया है।

इसलिए मुझे लगता है कि यह सिर्फ मैं नहीं हूं।

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

for each octet in Key
   AddTheOctetToTheHash

इसका मतलब यह है कि जैसे-जैसे चाबी मिलती है मुरमुर को चमकने का मौका मिलता है।


अपडेट करें

GUIDs अद्वितीय नहीं, बल्कि अद्वितीय होने के लिए डिज़ाइन किए गए हैं

रेमंड चेन द्वारा एक समय पर पोस्ट इस तथ्य को दोहराता है कि "यादृच्छिक" GUIDs का उपयोग उनकी यादृच्छिकता के लिए नहीं किया जाता है। वे, या उनमें से एक सबसेट, एक हैश कुंजी के रूप में अनुपयुक्त हैं:

यहां तक ​​कि संस्करण 4 GUID एल्गोरिदम अप्रत्याशित होने की गारंटी नहीं है, क्योंकि एल्गोरिथ्म यादृच्छिक संख्या जनरेटर की गुणवत्ता को निर्दिष्ट नहीं करता है। GUID के लिए विकिपीडिया लेख में प्राथमिक अनुसंधान शामिल है जो बताता है कि भविष्य और पिछले GUID को यादृच्छिक संख्या जनरेटर राज्य के ज्ञान के आधार पर भविष्यवाणी की जा सकती है, क्योंकि जनरेटर क्रिप्टोग्राफिक रूप से मजबूत नहीं है।

यादृच्छिकता टकराव से बचने के समान नहीं है; यही कारण है कि यह एक "यादृच्छिक" गाइड के कुछ सबसेट लेने के द्वारा अपने "हैशिंग" एल्गोरिथ्म का आविष्कार करने की कोशिश करने के लिए एक गलती होगी:

int HashKeyFromGuid(Guid type4uuid)
{
   //A "4" is put somewhere in the GUID.
   //I can't remember exactly where, but it doesn't matter for
   //the illustrative purposes of this pseudocode
   int guidVersion = ((type4uuid.D3 & 0x0f00) >> 8);
   Assert(guidVersion == 4);

   return (int)GetFirstFourBytesOfGuid(type4uuid);
}

नोट : फिर से, मैंने उद्धरण में "यादृच्छिक GUID" डाला , क्योंकि यह GUID का "यादृच्छिक" संस्करण है। अधिक सटीक वर्णन होगा Type 4 UUID। लेकिन किसी को नहीं पता कि टाइप 4, या टाइप 1, 3 और 5 क्या हैं। इसलिए उन्हें "यादृच्छिक" GUID कहना आसान है।

सभी अंग्रेजी शब्द दर्पण


41
यह देखना वास्तव में दिलचस्प होगा कि SHA की तुलना कैसे की जाती है, इसलिए नहीं कि यह यहाँ हैशिंग एल्गोरिथ्म के लिए एक अच्छा उम्मीदवार है, लेकिन यह देखना वास्तव में दिलचस्प होगा कि कोई भी क्रिप्टोग्राफ़िक हैश इन की तुलना स्पीड एल्गोरिदम से कैसे करता है।
माइकल

8
यन कोलेट द्वारा 'xxHash' नाम से एक नया हैश, हाल ही में दौर कर रहा था। मुझे हमेशा एक नए हैश का संदेह है। यह आपकी तुलना में देखना दिलचस्प होगा, (यदि आप लोगों को यादृच्छिक हैश का सुझाव देते नहीं थक रहे हैं तो उन्होंने जोड़ा है ...)
th_in_gs

7
वास्तव में। XxHash प्रोजेक्ट पृष्ठ द्वारा घोषित प्रदर्शन संख्या प्रभावशाली दिखती है, शायद यह सच है। खैर, कम से कम, यह एक ओपन-सोर्स प्रोजेक्ट है: code.google.com/p/xxhash
ATTracker

9
हाय इयान, मेरी डेल्फी का सुपरफास्ट हश का कार्यान्वयन सही है। लागू करते समय मैंने अपने कार्यान्वयन और संदर्भ कार्यान्वयन के परिणामों की तुलना करने के लिए सी और डेल्फी में एक परीक्षण सेट बनाया। कोई मतभेद नहीं हैं। तो आप जो देख रहे हैं वह हैश की वास्तविक दुष्टता है ... (यही कारण है कि मैंने एक मर्मराहश कार्यान्वयन भी प्रकाशित किया: Landman-code.blogspot.nl/2009/02/… )
Davy Landman

19
क्या पोस्टर के बारे में पता है कि यह सिर्फ एक भयानक जवाब नहीं है - यह इस विषय पर दुनिया का वास्तविक संदर्भ संसाधन है? कभी भी मुझे हैश से निपटने की आवश्यकता होती है, जो मेरे मुद्दे को इतनी तेजी से और आधिकारिक रूप से हल करता है कि मुझे कभी और किसी चीज की आवश्यकता नहीं है।
MaiaVictor

59

यदि आप एक अपरिवर्तनीय शब्दकोश से हैश मैप बनाना चाहते हैं, तो आप हैश फंक्शन पर विचार करना चाह सकते हैं https://en.wikipedia.org/wiki/Perfect_hash_function - हैश फ़ंक्शन और हैश टेबल के निर्माण के दौरान, आप गारंटी दे सकते हैं, किसी दिए गए डेटासेट के लिए, कि कोई टक्कर नहीं होगी।


2
प्रदर्शन डेटा सहित यहां (न्यूनतम) परफेक्ट हाशिंग burtleburtle.net/bob/hash/perfect.html के बारे में अधिक जानकारी दी गई है , हालांकि यह सबसे वर्तमान प्रोसेसर आदि का उपयोग नहीं करता है
एली केसलमैन

4
यह बहुत स्पष्ट है, लेकिन यह इंगित करने के लायक है कि बिना टकराव की गारंटी देने के लिए, कुंजियों को मानों के समान आकार देना होगा, जब तक कि एल्गोरिथ्म को कैपिटलाइज़ कर सकते हैं मूल्यों पर बाधाएं नहीं होती हैं।
devios1

1
@ devios1 आपका कथन निरर्थक है। सबसे पहले, हैश तालिका में मान, सही या नहीं, कुंजियों से स्वतंत्र हैं। दूसरा, एक सही हैश तालिका मूल्यों का एक रैखिक सरणी है, जिसे फ़ंक्शन के परिणाम द्वारा अनुक्रमित किया गया है ताकि इसे तैयार किया गया हो ताकि सभी सूचकांक अद्वितीय हों।
जिम बैटर

1
@MarcusJ परफेक्ट हैशिंग आमतौर पर 100 से कम कुंजियों के साथ प्रयोग किया जाता है, लेकिन cmph.sourceforge.net पर एक नज़र डालें ... अभी भी आपकी सीमा से कम है।
जिम बेल्टर

1
@DavidCary आपके लिंक पर कुछ भी आपके दावे का समर्थन नहीं करता है। संभवतः आपने ओ (1) को "कोई टक्कर नहीं" के साथ भ्रमित किया है, लेकिन वे सभी एक ही चीज़ पर नहीं हैं। बेशक, परफेक्ट हैशिंग कोई टकराव की गारंटी नहीं देते हैं, लेकिन इसके लिए आवश्यक है कि सभी कुंजियाँ पहले से ज्ञात हों और उनमें से कुछ अपेक्षाकृत कम हों। (लेकिन ऊपर सेमी का लिंक देखें।)
जिम

34

यहाँ हैश फ़ंक्शंस की एक सूची है, लेकिन लघु संस्करण है:

यदि आप बस एक अच्छा हैश फ़ंक्शन रखना चाहते हैं, और प्रतीक्षा नहीं कर सकते हैं, djb2तो मुझे पता है कि सबसे अच्छा स्ट्रिंग हैश फ़ंक्शन में से एक है। यह कुंजी और टेबल आकार के कई अलग-अलग सेटों पर उत्कृष्ट वितरण और गति है

unsigned long
hash(unsigned char *str)
{
    unsigned long hash = 5381;
    int c;

    while (c = *str++)
        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */

    return hash;
}

6
वास्तव में djb2 सबसे संवेदनशील हैश कार्यों के रूप में शून्य संवेदनशील है, इसलिए आप इस तरह के हैश को आसानी से तोड़ सकते हैं। यह एक बुरा पूर्वाग्रह भी कई टकराव और एक बुरा वितरण है, यह सबसे स्मैशर गुणवत्ता परीक्षणों पर टूटता है: देखें github.com/rurban/smhasher/blob/master/doc/bernstein उनका cdb डेटाबेस इसका उपयोग करता है, लेकिन मैं इसका उपयोग नहीं करूंगा सार्वजनिक पहुंच के साथ।
रब

2
डीजेबी एक प्रदर्शन और वितरण के दृष्टिकोण से बहुत खराब है। मैं आज इसका इस्तेमाल नहीं करता।
कॉनरेड मेयर

@ConradMeyer मैं शर्त लगा सकता हूँ, DJB को मेरे इस प्रश्न में तीन के एक कारक के रूप में देखा जा सकता है और फिर यह शायद सबसे उपयोगी एल्गोरिदम को हरा देगा। वितरण के संबंध में, मैं सहमत हूं। दो अक्षर तार के लिए भी हैश उत्पादक टकराव वास्तव में अच्छा नहीं हो सकता।
मातरिनस

28

Google द्वारा CityHash वह एल्गोरिथ्म है जिसे आप खोज रहे हैं। यह क्रिप्टोग्राफी के लिए अच्छा नहीं है, लेकिन अद्वितीय हैश पैदा करने के लिए अच्छा है।

अधिक विवरण के लिए ब्लॉग पढ़ें और यहां कोड उपलब्ध है

CityHash C ++ में लिखा गया है। एक प्लेन सी पोर्ट भी है ।

लगभग 32-बिट समर्थन:

सभी सिटीहैश फ़ंक्शन 64-बिट प्रोसेसर के लिए ट्यून किए गए हैं। कहा कि, वे 32-बिट कोड में (नए वाले को छोड़कर SSE4.2 का उपयोग करने वाले) को चलाएंगे। वे हालांकि बहुत तेज़ नहीं होंगे। आप 32-बिट कोड में मुरमुर या कुछ और का उपयोग करना चाह सकते हैं।


11
क्या CityHash का उच्चारण "सिटी सुशी" के समान है?
एरिक

2
SipHash पर भी नजर डालें, इसका मतलब मुरमुरश / CityHash / etc को बदलना है। : 131002.net/siphash
एडविन

3
साथ ही सिटीहैश के उत्तराधिकारी फ़ार्मश को भी देखें। code.google.com/p/farmhash
stevendaniels

7
xxHash CityHash की तुलना में 5 गुना तेज होने का दावा करता है।
क्ले ब्रिजेज

plain C portलिंक टूट गया है
निर्माताj

20

मैंने हैशिंग फ़ाइलों के दौरान विभिन्न हैशिंग एल्गोरिदम की एक छोटी गति तुलना की साजिश रची है।

व्यक्तिगत भूखंड केवल पढ़ने की विधि में थोड़ा भिन्न होते हैं और यहां पर ध्यान नहीं दिया जा सकता है, क्योंकि सभी फाइलें एक tmpfs में संग्रहीत की गई थीं। इसलिए अगर आप सोच रहे हैं तो बेंचमार्क IO- बाउंड नहीं था।

एल्गोरिदम में शामिल हैं SpookyHash, CityHash, Murmur3, MD5, SHA{1,256,512}:।

निष्कर्ष:

  • नॉन-क्रिप्टोग्राफिक हैश फंक्शन जैसे मर्मर 3, सिटीश और स्पूकी काफी करीब हैं। ध्यान दें कि SSE 4.2s CRCइंस्ट्रक्शन के साथ CPU पर Cityhash तेज हो सकता है , जो कि मेरे CPU के पास नहीं है। SpookyHash सिटीहैश से पहले मेरे मामले में हमेशा एक छोटा सा था।
  • क्रिप्टोग्राफिक हैश फ़ंक्शंस का उपयोग करते समय एमडी 5 एक अच्छा ट्रेडऑफ़ लगता है, हालांकि एमडी 5 और एसएचए 1 की टक्कर भेद्यता के लिए SHA256 अधिक सुरक्षित हो सकता है ।
  • सभी एल्गोरिदम की जटिलता रेखीय है - जो वास्तव में आश्चर्यजनक नहीं है क्योंकि वे ब्लॉकवाइज काम करते हैं। (मैं देखना चाहता था कि क्या रीडिंग मेथड से फर्क पड़ता है, इसलिए आप सही मानों की तुलना कर सकते हैं)।
  • SHA512 SHA512 की तुलना में धीमा था।
  • मैंने हैश कार्यों की यादृच्छिकता की जांच नहीं की। लेकिन यहाँ हैन फ़ंक्शंस की एक अच्छी तुलना है जो इयान बॉयड्स के उत्तर में गायब हैं । यह बताता है कि सिटीहैश को कोने के मामलों में कुछ समस्याएं हैं।

स्रोत का उपयोग भूखंडों के लिए किया जाता है:


1
रैखिक स्केल ग्राफ y- अक्ष लेबल को काटता है जो कहता है कि यह किस मात्रा में प्लॉटिंग है। मुझे लगता है कि यह "सेकंड में समय" होगा, लॉगरिदमिक पैमाने के समान। यह तय करने लायक है।
क्रेग मैकक्वीन

18

SHA एल्गोरिदम (SHA-256 सहित) को तेज़ बनाने के लिए डिज़ाइन किया गया है ।

वास्तव में, उनकी गति कभी-कभी एक समस्या हो सकती है। विशेष रूप से, पासवर्ड-व्युत्पन्न टोकन को संग्रहीत करने के लिए एक सामान्य तकनीक 10,000 बार एक मानक फास्ट हैश एल्गोरिथ्म को चलाने के लिए है (पासवर्ड ...) के हैश के हैश के हैश को संग्रहीत करना।

#!/usr/bin/env ruby
require 'securerandom'
require 'digest'
require 'benchmark'

def run_random_digest(digest, count)
  v = SecureRandom.random_bytes(digest.block_length)
  count.times { v = digest.digest(v) }
  v
end

Benchmark.bmbm do |x|
  x.report { run_random_digest(Digest::SHA256.new, 1_000_000) }
end

आउटपुट:

Rehearsal ------------------------------------
   1.480000   0.000000   1.480000 (  1.391229)
--------------------------- total: 1.480000sec

       user     system      total        real
   1.400000   0.000000   1.400000 (  1.382016)

57
क्रिप्टोग्राफ़िक हैशिंग एल्गोरिथ्म के लिए यह अपेक्षाकृत तेज़ है, निश्चित है । लेकिन ओपी केवल एक हैशटेबल में मूल्यों को संग्रहीत करना चाहता है, और मुझे नहीं लगता कि क्रिप्टोग्राफिक हैश फ़ंक्शन वास्तव में इसके लिए उपयुक्त है।
डीन हार्डिंग

6
प्रश्न क्रिप्टोग्राफिक हैश फ़ंक्शन के विषय के अनुसार लाया गया है (tangentially, यह अब प्रकट होता है)। वह बिट मैं जवाब दे रहा हूं।
yfeldblum

15
बस लोगों को "विशेष रूप से, एक पासवर्ड-व्युत्पन्न टोकन को संग्रहीत करने के लिए एक सामान्य तकनीक एक मानक फास्ट हैश एल्गोरिथ्म को 10,000 बार चलाने के लिए है" के विचार को बंद करने के लिए - जबकि आम है, यह सिर्फ सादे बेवकूफ है। इन परिदृश्यों के लिए डिज़ाइन किए गए एल्गोरिदम हैं, उदाहरण के लिए bcrypt,। सही उपकरण का उपयोग करें।
टीसी 1

3
क्रिप्टोग्राफिक हैश को उच्च थ्रूपुट के लिए डिज़ाइन किया गया है, लेकिन अक्सर इसका मतलब है कि उनके पास उच्च सेटअप, फाड़ .rodataऔर / या राज्य लागत है। जब आप एक हैशटेबल के लिए एक एल्गोरिथ्म चाहते हैं, तो आपके पास आमतौर पर बहुत कम चाबियाँ होती हैं, और उनमें से बहुत सी होती हैं, लेकिन एक क्रिप्टोग्राफिक की अतिरिक्त गारंटी की आवश्यकता नहीं होती है। मैं एक ट्विन जेनकींस का उपयोग खुद एक बार करता हूं।
mirabilos

1
@ क्रिसमोरगन: एक क्रिप्टोग्राफिक रूप से सुरक्षित हैश का उपयोग करने के बजाय, हैशटेबल DoS को हैश रैंडमाइजेशन का उपयोग करके बहुत अधिक कुशलता से हल किया जा सकता है, ताकि हर रन प्रोग्राम या हर हैशटेबल पर चले, इसलिए डेटा हर बार एक ही बाल्टी में समूहीकृत नहीं होता है। ।
रयान

14

मुझे पता है कि SHA-256 और इस तरह की चीजें हैं, लेकिन इन एल्गोरिदम को सुरक्षित बनाने के लिए डिज़ाइन किया गया है , जिसका अर्थ है कि वे एल्गोरिदम की तुलना में धीमी हैं जो कम अद्वितीय हैं

क्रिप्टोग्राफ़िक हैश फ़ंक्शंस अधिक अद्वितीय हैं यह धारणा गलत है, और वास्तव में यह व्यवहार में अक्सर पीछे की ओर दिखाया जा सकता है। सच्चाई में:

  1. क्रिप्टोग्राफिक हैश फ़ंक्शन आदर्श रूप से यादृच्छिक से अप्रभेद्य होना चाहिए ;
  2. लेकिन गैर-क्रिप्टोग्राफिक हैश फ़ंक्शन के साथ, संभावित इनपुट के साथ अनुकूल रूप से बातचीत करना उनके लिए वांछनीय है

जिसका अर्थ है कि एक गैर-क्रिप्टोग्राफ़िक हैश फ़ंक्शन "अच्छा" डेटा सेट के लिए एक क्रिप्टोग्राफ़िक से कम टकराव हो सकता है - डेटा सेट जो इसके लिए डिज़ाइन किया गया था।

हम वास्तव में इयान बॉयड के उत्तर में डेटा और गणित के एक बिट के साथ प्रदर्शित कर सकते हैं: जन्मदिन की समस्या । यदि आप nसेट से यादृच्छिक पर पूर्णांकों को लेते हैं, तो जोड़े जाने की अपेक्षित संख्या का सूत्र [1, d]यह है (विकिपीडिया से लिया गया):

n - d + d * ((d - 1) / d)^n

प्लगिंग n= 216,553 और d= 2 ^ 32 हमें लगभग 5.5 अपेक्षित टक्कर मिलती हैं । इयान के परीक्षण ज्यादातर उस पड़ोस के आसपास परिणाम दिखाते हैं, लेकिन एक नाटकीय अपवाद के साथ: अधिकांश कार्यों को लगातार संख्या परीक्षणों में शून्य टकराव मिला । यादृच्छिक पर 216,553 32-बिट संख्या चुनने और शून्य टक्कर प्राप्त करने की संभावना लगभग 0.43% है। और यह सिर्फ एक समारोह के लिए है - यहाँ हम शून्य टकराव वाले पांच अलग - अलग हैश फ़ंक्शन परिवार हैं !

तो हम यहां जो देख रहे हैं, वह यह है कि इयान ने जिस हैश का परीक्षण किया है , वह लगातार संख्या के डेटासेट के साथ अनुकूलता से बातचीत कर रहा है - यानी, वे एक आदर्श क्रिप्टोग्राफ़िक हैश फ़ंक्शन की तुलना में न्यूनतम भिन्न इनपुट्स को अधिक व्यापक रूप से फैला रहे हैं । (साइड नोट: इसका मतलब यह है कि इयान के ग्राफिकल मूल्यांकन कि FNV-1a और MurmurHash2 "यादृच्छिक दिखते हैं" उसे संख्या डेटा सेट में अपने स्वयं के डेटा से मना किया जा सकता है। उस आकार के डेटा सेट पर शून्य टकराव, दोनों हैश कार्यों के लिए। हड़ताली गैर-आयामी है! "

यह आश्चर्य की बात नहीं है क्योंकि यह हैश कार्यों के कई उपयोगों के लिए एक वांछनीय व्यवहार है। उदाहरण के लिए, हैश टेबल कीज़ अक्सर बहुत समान होती हैं; इयान के जवाब में एक समस्या एमएसएन के पास एक बार ज़िप कोड हैश टेबल के साथ होने का उल्लेख है । यह एक ऐसा प्रयोग है जहाँ संभावना आदानों पर टकराव से बचाव यादृच्छिक-समान व्यवहार पर जीत हासिल करता है।

यहाँ एक और शिक्षाप्रद तुलना CRC और क्रिप्टोग्राफ़िक हैश फ़ंक्शंस के बीच डिज़ाइन लक्ष्यों में विपरीत है:

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

इसलिए सीआरसी के लिए न्यूनतम भिन्न इनपुट में यादृच्छिक से कम टकराव होना फिर से अच्छा है। क्रिप्टो हैश के साथ, यह एक नहीं-नहीं है!


10

SipHash का उपयोग करें । इसके कई वांछनीय गुण हैं:

  • फास्ट। एक अनुकूलित कार्यान्वयन प्रति बाइट लगभग 1 चक्र लेता है।

  • सुरक्षित। SipHash एक मजबूत PRF (छद्म आयामी समारोह) है। इसका मतलब है कि यह एक यादृच्छिक कार्य से अप्रभेद्य है (जब तक कि आप 128-बिट गुप्त कुंजी नहीं जानते हैं)। अत:

    • टकराव के कारण आपके हैश टेबल जांच के रैखिक होने की चिंता करने की कोई आवश्यकता नहीं है। SipHash के साथ, आप जानते हैं कि आपको इनपुट पर ध्यान दिए बिना औसत-औसत प्रदर्शन मिलेगा।

    • हैश-आधारित सेवा हमलों से इनकार करने की प्रतिरक्षा।

    • आप SipHash (विशेष रूप से 128-बिट आउटपुट के साथ संस्करण) का उपयोग मैक (संदेश प्रमाणीकरण कोड) के रूप में कर सकते हैं। यदि आपको कोई संदेश और SipHash टैग प्राप्त होता है, और टैग वही है जो आपकी गुप्त कुंजी के साथ SipHash को चलाने से है, तो आप जानते हैं कि जिसने भी हैश बनाया है वह आपकी गुप्त कुंजी के कब्जे में है, और यह कि न तो संदेश और न ही संदेश हैश के बाद से बदल दिया गया है।


1
जब तक आपको सुरक्षा की आवश्यकता न हो, क्या SipHash ओवरकिल नहीं है? 128-बिट कुंजी की आवश्यकता है जो कि महिमामंडित हैश बीज है। मुरमुरैश का उल्लेख नहीं करने के लिए 128-बिट आउटपुट है और सिफैश में केवल 64-बिट आउटपुट है। जाहिर है कि बड़े पाचन में कम टक्कर का मौका होता है।
bryc

@bryc अंतर यह है कि SipHash को अच्छी तरह से व्यवहार करना जारी रहेगा, यहां तक ​​कि दुर्भावनापूर्ण इनपुट पर भी। SipHash पर आधारित एक हैश तालिका का उपयोग संभावित शत्रुतापूर्ण स्रोतों से डेटा के लिए किया जा सकता है, और एक एल्गोरिथ्म जैसे रैखिक जांच का उपयोग कर सकते हैं जो हैश फ़ंक्शन के विवरण के लिए बहुत संवेदनशील है।
डेमी

9

यह उस डेटा पर निर्भर करता है जिस पर आप हैशिंग हैं। कुछ हैशिंग टेक्स्ट जैसे विशिष्ट डेटा के साथ बेहतर काम करते हैं। कुछ हैशिंग एल्गोरिदम विशिष्ट डेटा के लिए अच्छे होने के लिए डिज़ाइन किए गए विशिष्ट थे।

पॉल हेशिह ने एक बार उपवास किया था । वह स्रोत कोड और स्पष्टीकरण सूचीबद्ध करता है। लेकिन यह पहले ही पिट गया था। :)


6

जावा इस सरल गुणा-और-जोड़ एल्गोरिथ्म का उपयोग करता है:

एक स्ट्रिंग ऑब्जेक्ट के लिए हैश कोड के रूप में गणना की जाती है

 s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

पूर्णांक गणित, जहां का उपयोग कर s[i]रहा है मैं स्ट्रिंग के मई के चरित्र, nस्ट्रिंग की लंबाई है, और ^घातांक इंगित करता है। (खाली स्ट्रिंग का हैश मान शून्य है।)

वहाँ शायद बहुत बेहतर हैं, लेकिन यह काफी व्यापक है और गति और विशिष्टता के बीच एक अच्छा व्यापार बंद लगता है।


12
मैं यहां इस्तेमाल किए गए सटीक समान का उपयोग नहीं करूंगा, क्योंकि अभी भी इसके साथ टकराव पैदा करना अपेक्षाकृत आसान है। यह निश्चित रूप से भयानक नहीं है, लेकिन वहां बहुत बेहतर हैं। और अगर जावा के साथ संगत होने का कोई महत्वपूर्ण कारण नहीं है, तो इसे चुना नहीं जाना चाहिए ।
जोकिम सॉयर

4
यदि आप अभी भी किसी कारण से हैशिंग के इस तरीके को चुनते हैं, तो आप कम से कम 92821 जैसे एक बेहतर प्राइमरी का उपयोग एक गुणक के रूप में कर सकते हैं। यह टकराव को कम करता है। stackoverflow.com/a/2816747/21499
हंस-पीटर स्टॉरर

1
आप इसके बजाय FNV1a का उपयोग कर सकते हैं। यह एक सरल गुणन-आधारित हैश भी है, लेकिन एक बड़े गुणक का उपयोग करता है, जो हैश को बेहतर तरीके से फैलाता है।
bryc

4

सबसे पहले, आपको अपने स्वयं के हैशिंग को लागू करने की आवश्यकता क्यों है? अधिकांश कार्यों के लिए आपको एक मानक पुस्तकालय से डेटा संरचनाओं के साथ अच्छे परिणाम प्राप्त करने चाहिए, यह मानते हुए कि एक कार्यान्वयन उपलब्ध है (जब तक कि आप केवल अपनी शिक्षा के लिए ऐसा नहीं कर रहे हैं)।

जहां तक ​​वास्तविक हैशिंग एल्गोरिदम की बात है, मेरा व्यक्तिगत पसंदीदा एफएनवी है। 1

यहाँ C में 32-बिट संस्करण का एक उदाहरण कार्यान्वयन है:

unsigned long int FNV_hash(void* dataToHash, unsigned long int length)
{
  unsigned char* p = (unsigned char *) dataToHash;
  unsigned long int h = 2166136261UL;
  unsigned long int i;

  for(i = 0; i < length; i++)
    h = (h * 16777619) ^ p[i] ;

  return h;
}

2
एफएनवी -1 ए वेरिएंट यादृच्छिकता के साथ थोड़ा बेहतर है। के ऑर्डर को स्वैप करें *और ^: h = (h * 16777619) ^ p[i]==>h = (h ^ p[i]) * 16777619
इयान बॉयड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.