मैंने कुछ अलग एल्गोरिदम का परीक्षण किया, गति और टकराव की संख्या को मापा।
मैंने तीन अलग-अलग कुंजी सेटों का उपयोग किया:
प्रत्येक कॉर्पस के लिए, हैशिंग और औसत समय बिताया हैशिंग की संख्या दर्ज की गई थी।
मैंने परीक्षण किया:
परिणाम
प्रत्येक परिणाम में औसत हैश समय और टकराव की संख्या होती है
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 का उपयोग उनकी यादृच्छिकता के लिए नहीं किया जाता है। वे, या उनमें से एक सबसेट, एक हैश कुंजी के रूप में अनुपयुक्त हैं:
यहां तक कि संस्करण 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 कहना आसान है।
सभी अंग्रेजी शब्द दर्पण