Mikä hajautusalgoritmi on paras ainutlaatuisuudelle ja nopeudelle?

Mikä hajautusalgoritmi on paras ainutlaatuisuuden ja nopeuden saavuttamiseksi? Esimerkkejä (hyvistä) käyttötavoista ovat hash-sanakirjat.

Tiedän, että on asioita, kuten SHA-256 ja vastaavia, mutta nämä algoritmit ovat suunniteltu olemaan turvallinen , mikä tarkoittaa yleensä, että ne ovat hitaampia kuin algoritmit jotka ovat vähemmän ainutlaatuisia . Haluan hash-algoritmin, joka on suunniteltu nopeaksi, mutta kuitenkin melko ainutlaatuiseksi törmäysten välttämiseksi.

Kommentit

  • Mihin tarkoitukseen, turvallisuuteen tai muuhun?
  • @Orbling, hash-sanakirjan toteuttamiseen. Joten törmäykset tulisi pitää mahdollisimman vähäisinä, mutta sillä ei ole lainkaan turvatarkoitusta.
  • Huomaa, että sinun on odotettava vähintään joitain törmäyksiä hash-taulukossa, muuten taulukon on oltava valtava, jotta se pystyy käsittelemään jopa suhteellisen pienen määrän avaimia …
  • Loistava viesti! Voisitko tarkistaa myös ’ s Yann Collet ’ s xxHash (luoja tai LZ4), joka on kaksi kertaa nopeampi kuin Murmur? Kotisivu: code.google.com/p/xxhash Lisätietoja: fastcompression.blogspot.fr/2012/ 04 / …
  • @zvrba Riippuu algoritmista. bcrypt on suunniteltu hitaaksi.

Vastaus

Testasin joitain erilaisia algoritmeja, mittaamalla nopeuden ja törmäysten määrän .

Käytin kolmea erilaista avainsarjaa:

Jokaisen korpusen kohdalla törmäysten määrä ja keskimääräinen hajautukseen käytetty aika äänitettiin.

Testasin:

Tulokset

Jokainen tulos sisältää keskimääräisen hajautusajan ja törmäysten määrän

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 

Huomautuksia :

Tapahtuuko törmäyksiä todella?

Kyllä. Aloin kirjoittaa testiohjelmaani nähdäksesi, tapahtuvatko hash-törmäykset todella – eivätkä ne ole vain teoreettisia rakenteita.Ne todellakin tapahtuvat:

FNV-1-törmäykset

  • creamwove törmää quists

FNV -1a törmäykset

  • costarring törmäävät liquid
  • declinate törmää macallums
  • altarage törmää zinke
  • altarages törmää zinkes

Murm2-törmäykset

  • cataract törmää periti
  • roquette törmää skivie
  • shawl törmää stormbound
  • dowlases törmää tramontane
  • cricketings törmää twanger
  • longans törmää whigs

DJB2-törmäysten kanssa

  • hetairas törmää mentioner
  • heliotropes törmää neurospora
  • depravement törmää serafins
  • stylist törmää subgenera
  • joyful törmää synaphea
  • redescribed törmää urites
  • dram törmää vivency

DJB2a-törmäykset

  • haggadot törmää kohtaan loathsomenesses
  • adorablenesses törmää rentability
  • playwright törmää snush
  • playwrighting törmää snushing
  • treponematoses törmää waterbeds

CRC32-törmäysten kanssa

  • codding törmää gnu
  • exhibiters törmää schlager

SuperFastHash-törmäyksiin

  • dahabiah törmää drapability
  • encharm törmää enclave
  • grahams törmää gramary
  • … katkaise 79 törmäystä …
  • night törmää vigil
  • törmää vigils
  • finks törmää vinic

Satunnaistaminen

Toinen subjektiivinen mitta on se, kuinka hajautukset ovat jakautuneet satunnaisesti. Tuloksena olevien HashTable-taulukoiden kartoitus osoittaa, kuinka tasaisesti tiedot jaetaan. Kaikilla hash-funktioilla on hyvä jakauma taulukon kartoituksessa lineaarisesti:

Kirjoita kuvan kuvaus tähän

Tai Hilbert-kartta ( XKCD on aina relevantti ):

Anna kuvan kuvaus tähän

Paitsi kun numerosarjaa hajautetaan ("1", "2", …, "216553") (esimerkiksi postinumero) , josta kuviot alkavat esiintyä useimmissa hajautusalgoritmeissa:

SDBM :

Kirjoita kuvan kuvaus tähän

DJB2a :

Kirjoita kuvan kuvaus tähän

FNV-1 :

Anna kuvan kuvaus tähän

Kaikki paitsi

FNV-1a , jotka näyttävät silti minulle melko satunnaisilta:

Kirjoita kuvan kuvaus tähän.

Itse asiassa Murmur2: lla näyttää olevan vielä parempi satunnaisuus Numbers kuin FNV-1a:

Anna kuvan kuvaus tähän

Kun katson FNV-1a ”numerokarttaa, I ajatella näen hienovaraisia pystysuoria kuvioita. Murmurin kanssa en näe lainkaan malleja. Mitä mieltä sinä olet?


Ylimääräinen * taulukossa osoittaa, kuinka huono satunnaisuus on. FNV-1a ollessa paras ja DJB2x huonoin:

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

Kirjoitin tämän ohjelman alunperin päättääksesi, pitäisikö minun edes huolehtia törmäyksistä: Minä.

Ja sitten muuttui sen varmistamiseksi, että hash-toiminnot olivat riittävän satunnaisia.

FNV-1a -algoritmi

FNV1-hash tulee muunnelmina, jotka palauta 32, 64, 128, 256, 512 ja 1024 bittiset hajautusarvot.

FNV-1a -algoritmi on:

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

Missä vakiot FNV_offset_basis ja FNV_prime riippuvat haluamastasi palautus hash-koosta :

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 

Katso lisätietoja kohdasta FNV-pääsivu .

Kaikki tulokset ovat 32-bittisellä muunnoksella.

FNV-1 parempi kuin FNV-1a?

Ei. FNV-1a on kaikkialla parempi. FNV-1a: n kanssa tapahtui enemmän törmäyksiä käytettäessä englanninkielistä sanaa corpus:

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

Vertaa nyt pieniä ja isoja kirjaimia:

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

Tässä tapauksessa FNV-1a ei ole” t ”400%” huonompi kuin FN-1, vain 20% huonompi.

Luulen, että tärkeämpi takeaway on, että törmäyksissä on kaksi algoritmiluokkaa:

  • törmäykset harvinaiset : FNV-1, FNV-1a, DJB2, DJB2a, SDBM
  • törmäykset yhteiset : SuperFastHash, Loselose

Ja sitten hashes jakautuvat tasaisesti:

  • erinomainen jakelu: Murmur2, FNV-1a, SuperFastHas
  • erinomainen jakelu: FNV-1
  • hyvä jakelu: SDBM, DJB2, DJB2a
  • kauhea jakelu: Loselose


Päivitä

Melu? Toki, miksi ei


Päivitä

@whatshisname ihmetteli kuinka CRC32 suoriutui, lisäsi numeroita taulukkoon.

CRC32 on melko hyvä . Harvat törmäykset, mutta hitaammat, ja 1 kt: n hakutaulukon yleiskustannukset.

Katkaise kaikki virheelliset asiat CRC-jakelusta – huono


Ylös tähän päivään asti aioin käyttää FNV-1a: ta de facto hash-taulukon hajautusalgoritmina. Mutta nyt vaihdan Murmur2: een:

  • Nopeampi
  • Parempi satunnaisluokittelu kaikista syöteluokista

Ja todella, todella toivon, että löytämässäni SuperFastHash algoritmissa on jotain vikaa ; se on liian huono olla yhtä suosittu kuin se on.

Päivitys: Lähteestä MurmurHash3-kotisivu Googlessa :

(1) – SuperFastHashilla on erittäin heikot törmäysominaisuudet, jotka on dokumentoitu muualla.

Joten luulen, että se ei ole vain minä.

Päivitys: Tajusin, miksi Murmur on muita nopeampi. MurmurHash2 toimii neljällä tavulla kerrallaan. Suurin osa algoritmeista on tavu tavuilta :

for each octet in Key AddTheOctetToTheHash 

Tämä tarkoittaa, että kun avaimet pitenevät, Murinalla on mahdollisuus loistaa.


Päivitä

GUID-tunnukset on suunniteltu yksilöllisiksi, ei satunnaisiksi

Raymond Chenin ajankohtainen viesti toistaa, että ”satunnaisia” GUID-tunnuksia ei ole tarkoitettu käytettäväksi niiden satunnaisuus. Ne tai niiden osa ei sovi hash-avaimeksi:

Jopa version 4 GUID-algoritmia ei voida taata arvaamattomaksi, koska algoritmi ei määritä satunnaislukugeneraattorin laatua. GUID: n Wikipedia-artikkeli sisältää ensisijaisen tutkimuksen, joka ehdottaa , että tulevaisuuden ja aiemmat GUID: t voidaan ennustaa satunnaislukugeneraattorin tilan perusteella, koska generaattoria ei ole salattu vahva.

Satunnaisuus ei ole sama kuin törmäyksen välttäminen; minkä vuoksi olisi virhe yrittää keksiä oma ”hajautus” -algoritmisi ottamalla jokin ”satunnainen” opasjoukko:

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); } 

Huomautus : Laitoin jälleen lainausmerkkeihin ”random GUID” , koska se on ”satunnainen” muunnos GUID-tiedostoista. Tarkempi kuvaus olisi Type 4 UUID. Mutta kukaan ei tiedä mikä tyyppi 4 tai tyypit 1, 3 ja 5 ovat. Joten on vain helpompaa kutsua niitä satunnaisiksi ”GUID: t.

Kaikki englanninkieliset sanat peilaa

kommentit

  • Olisi todella mielenkiintoista nähdä, kuinka SHA vertaa, ei siksi, että se ’ on hyvä ehdokas hajautusalgoritmille täällä, mutta se olisi todella mielenkiintoista nähdä, kuinka mikä tahansa salaushajautus vertaa nopeusalgoritmeille tehtyihin.
  • Uusi hash Yann Colletin tekemä ’ xxHash ’ oli tekemässä kierroksia äskettäin. ’ m aina epäilen uutta hajautusta. Olisi mielenkiintoista nähdä se vertailussa (jos et ole ’ kyllästynyt ihmisiin, jotka ehdottavat satunnaisia hajautuksia, joista he ’ ovat kuulleet lisätään …)
  • Todellakin. XxHash-projektisivun ilmoittamat suorituskyvynumerot näyttävät vaikuttavilta, ehkä liian suurilta totta. Ainakin se ’ on avoimen lähdekoodin projekti: code.google.com/p/xxhash
  • Hei Ian, SuperFastHashin Delphi-toteutus on oikein. Toteuttaessani loin testisarjan C: ssä ja Delphissä vertailemaan toteutukseni tuloksia ja viitetoteutusta. Eroja ei ole. Joten mitä näet on hashin todellinen pahuus … (Siksi julkaisin myös MurmurHash-toteutuksen: landman-code.blogspot.nl/2009/02/ … )
  • Onko julistaja tietoinen, että tämä ei ole vain mahtava vastaus – tämä on maailma ’ onko de facto aihepiirin lähde? Milloin tahansa minun on käsiteltävä hajautuksia, mikä ratkaisee ongelmani niin nopeasti ja auktoriteettisesti, että en koskaan ’ tarvitse koskaan mitään muuta.

Vastaa

Jos haluat luoda hash-kartan muuttumattomasta sanakirjasta, sinun kannattaa harkita täydellistä hajautusta https://en.wikipedia.org/wiki/Perfect_hash_function – hash-funktion ja hash-taulukon rakentamisen aikana voit taata tietylle tietojoukolle, ettei törmäyksiä tapahdu.

Kommentit

  • Tässä ’ lisää (täydellisestä) täydellisestä hajautuksesta burtleburtle.net/bob/hash/perfect.html mukaan lukien suorituskykytiedot, vaikka se ’ ei käytä uusinta prosessoria jne.
  • ’ on melko ilmeinen, mutta on syytä huomauttaa, että törmäysten välttämiseksi avainten on oltava samankokoisia kuin arvot, ellei Ei ole rajoituksia arvoille, joihin algoritmi voi hyödyntää.
  • @ devios1 Lauselmasi on merkityksetön. Ensinnäkin hash-taulukon arvot, täydelliset tai ei, ovat riippumattomia avaimista. Toiseksi täydellinen hash-taulukko on vain lineaarinen arvoryhmä, joka indeksoidaan funktion tuloksen avulla, joka on muotoiltu siten, että kaikki indeksit ovat yksilöllisiä.
  • @MarcusJ Perfect-hajautusta käytetään yleensä alle 100: lla. avaimet, mutta katso cmph.sourceforge.net … edelleen kaukana alueestasi.
  • @DavidCary Ei mitään linkki tukee vaatimustasi. Olet ehkä sekoittanut O (1): n ja ” ei törmäyksiä ”, mutta ne eivät ole ’ t lainkaan sama asia. Täydellinen hajautus ei tietenkään takaa törmäyksiä, mutta se vaatii, että kaikki avaimet tunnetaan etukäteen ja että niitä on suhteellisen vähän. (Mutta katso yllä oleva linkki cmph: ään.)

Vastaa

Tässä on luettelo hajautusfunktioista, mutta lyhyt versio on:

Jos haluat vain hyvän hash-toiminnon , ja en voi odottaa, djb2 on yksi parhaimmista merkkijonon tiivistefunktioista, jotka tiedän. Sillä on erinomainen jakelu ja nopeus monille erilaisille avain- ja taulukkokokoille.

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; } 

Kommentit

  • Itse asiassa djb2 on nollaherkkä, koska useimmat tällaiset yksinkertaiset hash-toiminnot, joten voit helposti rikkoa tällaiset hashit.Sillä on huono puolueellisuus, liian monta törmäystä ja huono jakauma, se hajoaa useimmissa smhasher-laatutesteissä: Katso github.com/rurban/smhasher/blob/master/doc/bernstein Hänen cdb-tietokantansa käyttää sitä, mutta en halua käyttää sitä ’ julkisen pääsyn kanssa.
  • DJB on melko huono suorituskyvyn ja jakelun kannalta. En halua ’ käyttää sitä tänään.
  • @ConradMeyer I ’ d vedon, DJB: tä voidaan nopeuttaa kerroin kolme aivan kuten tässä kysymyksessäni ja sitten ’ d voitti todennäköisesti kaikkein käyttökelpoisimmat algoritmit. Jakelun osalta olen samaa mieltä. Hajautus, joka tuottaa törmäyksiä jopa kahdelle kirjainmerkille, ’ ei voi olla todella hyvää.
  • Kaverit, minulla on epäilyksiä. Sanot, että djb2 on huono, mutta hyväksytyn vastauksen testitulokset osoittavat sen olevan hyvä.
  • Voit ainakin käyttää järkevää alkua, joka tuottaa vähemmän törmäyksiä 33: n sijasta. stackoverflow.com/a/2816747/21499

Vastaa

Googlen CityHash on etsimäsi algoritmi. Se ei ole hyvä salaukselle, mutta on hyvä luomaan ainutlaatuisia hajautuksia.

Lue lisätietoja -blogista ja -koodi on saatavilla täältä .

CityHash on kirjoitettu C ++: lla. Siellä on myös tavallinen C-portti .

Tietoja 32-bittisestä tuesta:

Kaikki CityHash-toiminnot on viritetty 64-bittisille prosessoreille. Se sanoi, että ne suoritetaan (lukuun ottamatta uusia, jotka käyttävät SSE4.2: ta) 32-bittisessä koodissa. He eivät kuitenkaan ole kovin nopeita. Haluat ehkä käyttää Murmuria tai jotain muuta 32-bittisessä koodissa.

Kommentit

  • Onko CityHash lausuttu samanlainen kuin ” City Sushi? ”
  • Onko sinulla katso myös SipHashia, se on tarkoitettu korvaamaan MurmurHash / CityHash / jne.: 131002.net/siphash
  • Katso myös FarmHash, a CitHashin seuraaja. code.google.com/p/farmhash
  • xxHash väittää olevansa viisi kertaa nopeampi kuin CityHash.
  • plain C port linkki on rikki

Vastaa

Olen piirtänyt lyhyen nopeusvertailun eri hajautusalgoritmeista hajauttaessasi tiedostoja.

Yksittäiset juovat eroavat vain hieman lukutavasta ja voidaan jättää tässä huomioimatta, koska kaikki tiedostot on tallennettu tmpfs-tiedostoon. Siksi vertailuarvo ei ollut IO-sidottu, jos mietit.

Algoritmeja ovat: SpookyHash, CityHash, Murmur3, MD5, SHA{1,256,512}.

Johtopäätökset:

  • Muut kuin kryptografiset hash-toiminnot, kuten Murmur3, Cityhash ja Spooky, ovat melko lähellä toisiaan. On huomattava, että Cityhash voi olla nopeampi suorittimissa, joissa on SSE 4.2s CRC -käsky, jota prosessorissani ei ole. SpookyHash oli minun tapauksessani aina vähän ennen CityHashia.
  • MD5 näyttää olevan hyvä kompromissi käytettäessä salauksen hash-toimintoja, vaikka SHA256 saattaa olla turvallisempi törmäyshaavoittuvuudet .
  • Kaikkien algoritmien monimutkaisuus on lineaarista – mikä ei todellakaan ole yllättävää, koska ne toimivat lohkona. (Halusin nähdä, onko lukumenetelmällä merkitystä, joten voit verrata oikeanpuoleisia arvoja.)
  • SHA256 oli hitaampaa kuin SHA512.
  • En tutkinut hash-toiminnot. Mutta tässä on hyvä vertailu hash-funktioista, jotka puuttuvat Ian Boydsin vastauksesta . Tämä osoittaa, että CityHashilla on joitain ongelmia kulmatapauksissa.

Tontteihin käytetty lähde:

kommentit

  • Lineaarinen asteikkokaavio katkaisee y-akselin etiketin, joka kertoo minkä määrän se piirtää. Luultavasti se olisi ” aika sekunteina ”, sama kuin logaritminen asteikko. ’ kannattaa korjata.

Vastaa

Tiedän, että on olemassa asioita, kuten SHA-256 ja vastaavia, mutta nämä algoritmit on suunniteltu olla turvallinen , mikä tarkoittaa yleensä, että ne ovat hitaampia kuin vähemmän ainutlaatuiset algoritmit.

Oletus, että salauksen hash-toiminnot ovat ainutlaatuisempia, on väärä, ja itse asiassa sen voidaan osoittaa olevan käytännössä usein taaksepäin. Todellisuudessa:

  1. salauksen hajautusfunktioiden tulisi ihanteellisesti olla erotettavissa satunnaisista ;
  2. Mutta ei-salauksellisilla hajautusfunktioilla niiden on toivottavaa olla suotuisassa vuorovaikutuksessa todennäköisten syötteiden kanssa .

Tämä tarkoittaa, että ei-salauksellisella hajautusfunktiolla voi hyvinkin olla vähemmän törmäyksiä kuin salausteksti ”hyvää” tietojoukkoa varten – tietojoukot, joille se on suunniteltu.

Voimme todellakin osoittaa tämän Ian Boydin vastauksessa olevilla tiedoilla ja vähän matematiikalla: syntymäpäiväongelma . Kaava odotetulle törmäysparien lukumäärälle, jos valitset n kokonaislukuja satunnaisesti joukosta [1, d] on tämä (otettu Wikipediasta):

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

n = 216 553 ja d = 2 ^ 32 saamme noin 5.5 odotettavissa olevat törmäykset . Ianin testit osoittavat enimmäkseen tuloksia kyseisen naapuruston ympärillä, mutta yhtä dramaattista poikkeusta lukuun ottamatta: Suurin osa toiminnoista sai nollatörmäykset peräkkäiset numerotestit. Todennäköisyys valita 216 553 32-bittistä numeroa satunnaisesti ja saada nollatörmäykset on noin 0,43%. Ja se on vain yhtä toimintoa varten – tässä meillä on viisi erillistä hash-toimintoperhettä nolla törmäykset!

Joten mitä me täällä näemme, on se, että Ianin testaamat hashit ovat vuorovaikutuksessa suotuisasti peräkkäisten numeroiden kanssa – ts. ne hajaantuvat uudelleen minimaalisesti erilaisiksi panokset laajemmin kuin ihanteellinen kryptografinen hajautusfunktio. (Sivuhuomautus: tämä tarkoittaa, että Ianin graafinen arvio siitä, että FNV-1a ja MurmurHash2 ”näyttävät hänelle satunnaisilta” numerotietojoukossa, voidaan kumota hänen omasta datastaan. Nollatörmäykset tämän kokoisessa tietojoukossa, kun molemmat hash-toiminnot ovat silmiinpistävän satunnaisia!)

Tämä ei ole yllätys, koska tämä on toivottavaa käyttäytymistä monille hash-toimintojen käytöille. Esimerkiksi hash-taulukon avaimet ovat usein hyvin samanlaisia; Ianin vastauksessa mainitaan ongelma, joka MSN: llä oli kerran postinumeron hash-taulukoiden kanssa. Tämä on käyttö, jossa törmäyksen välttäminen todennäköisillä syötteillä voittaa satunnaiskäyttäytymisen.

Toinen opettava vertailu on CRC: n ja kryptografisten hajautusfunktioiden välinen kontrasti suunnittelutavoitteissa:

  • CRC on suunniteltu tarttumaan virheisiin, jotka johtuvat meluisista viestintäkanavista , jotka todennäköisesti pieni määrä bittikäännöksiä;
  • salaushajautukset on suunniteltu tarttumaan haitallisten hyökkääjien tekemiin muokkauksiin , joille on varattu rajalliset laskennalliset resurssit, mutta mielivaltaisesti paljon älykkyyttä.

Joten CRC: lle on jälleen hyvä , että törmäyksiä on vähemmän kuin satunnaisia minimaalisesti erilaisissa syötteissä. Salaushajautuksissa tämä on ei-ei!

Vastaus

SHA-algoritmit (mukaan lukien SHA-256) ovat suunniteltu nopeasti .

Itse asiassa niiden nopeus voi joskus olla ongelma. Erityisesti yleinen tekniikka salasanasta johdetun tunnuksen tallentamiseksi on tavallisen nopean hash-algoritmin suorittaminen 10000 kertaa (… salasanan hash-tiivisteen hash-muistin tallentaminen).

#!/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 

Tulos:

Rehearsal ------------------------------------ 1.480000 0.000000 1.480000 ( 1.391229) --------------------------- total: 1.480000sec user system total real 1.400000 0.000000 1.400000 ( 1.382016) 

Kommentit

  • ’ on suhteellisen nopea, varma, salauksen hajautusalgoritmille . Mutta OP haluaa vain tallentaa arvot hashtableen, enkä ’ usko, että salauksen hash-toiminto on todella sopiva siihen.
  • Esitetty kysymys (tangentiaalisesti se näyttää nyt) salauksen hajautusfunktioiden kohde. Se ’ on se bitti, johon vastaan.
  • Pelkästään ihmisten syrjäyttämiseksi ajatuksesta ” , yleinen tekniikka salasanasta johdetun tunnuksen tallentamiseksi on suorittaa vakioinen nopea hajautusalgoritmi 10000 kertaa ” – vaikka se on yleistä, ’ S vain tyhmä. Näitä tilanteita varten on suunniteltu algoritmeja, esim. bcrypt. Käytä oikeita työkaluja.
  • Salaushajautukset on suunniteltu siten, että niiden suorituskyky on suuri, mutta se tarkoittaa usein, että niillä on korkeat määritykset, repeytymiset, .rodata ja / tai valtion kustannukset .Kun haluat algoritmin hashtabelle, sinulla on yleensä hyvin lyhyet avaimet, ja paljon niitä, mutta et tarvitse salaustodistuksen lisävakuuksia. Käytän itse muokattua Jenkinsin yksi kerrallaan.
  • @ChrisMorgan: Sen sijaan, että käyttäisin kryptografisesti suojattua hashia, HashTable DoS voidaan ratkaista paljon tehokkaammin käyttämällä hash-satunnaistamista, jotta jokainen ohjelmissa tai edes jokaisella hashtabella, joten tietoja ei ’ ei ryhmitellä samaan ryhmään joka kerta.

Vastaa

Käytä SipHashia . Sillä on monia toivottavia ominaisuuksia:

  • Nopea. Optimoitu toteutus vie noin yhden jakson tavua kohti.

  • Suojattu. SipHash on vahva PRF (näennäissatunnaisfunktio). Tämä tarkoittaa, että sitä ei voida erottaa satunnaisfunktiosta (ellet tiedä 128-bittistä salaista avainta). Siksi:

    • Ei tarvitse huolehtia siitä, että hash-taulukon anturit muuttuvat lineaarisiksi törmäysten vuoksi. SipHashin avulla tiedät , että saat keskimääräisen suorituskyvyn keskimäärin syötteistä riippumatta.

    • Immuniteetti hash-pohjaisiin palvelunestohyökkäyksiin.

    • Voit käyttää SipHashia (etenkin versiota, jossa on 128-bittinen lähtö) MAC-tiedostona (Viestien todennuskoodi). Jos saat viestin ja SipHash-tunnisteen, ja tunniste on sama kuin SipHashin suorittamisessa salaisella avaimellasi, tiedät, että kuka tahansa hajautusasiakirjan luoja oli myös salaisen avaimesi hallussa ja ettei viesti eikä hashia on muutettu siitä lähtien.

Kommentit

  • Ei ’ t SipHash ylittää, ellet tarvitse suojausta? Vaatii 128-bittisen avaimen, joka on vain ylistetty hash-siemen. MurmurHash3: lla on 128-bittinen lähtö ja SipHashilla vain 64-bittinen lähtö. Suuremmalla katteella on tietysti pienempi törmäysmahdollisuus.
  • @bryc Ero on siinä, että SipHash käyttäytyy edelleen hyvin myös haitallisilla syötteillä. SipHashiin perustuvaa hajautustaulukkoa voidaan käyttää potentiaalisesti vihamielisistä lähteistä saatavaan dataan, ja siinä voidaan käyttää algoritmia, kuten lineaarista koetusta, joka on erittäin herkkä hajautusfunktion yksityiskohdille.
  • Siphash (ja siihen liittyvät uudemmat prng: t) tyylitoiminnot) on oletusvalintani turvallisuudelle. Suorituskyvyn kannalta xxhashia on vaikea voittaa. Internetissä on paljon pahoja hajautusneuvoja, jopa täällä käytävissä keskusteluissa. Hyvä suorituskyky satunnaisilla tai puoli satunnaisilla syötteillä on merkityksetöntä. Mikä on pahimmassa tapauksessa suorituskyky reaalimaailman panoksilla? Mikä on tulos haitallisilla syötteillä? Hajautustaulukostasi tulee lopulta hyökkäysvektori.

Vastaa

Se riippuu hajauttamistasi tiedoista. Jotkut hajautus toimii paremmin tiettyjen tietojen, kuten tekstin, kanssa. Jotkut hajautusalgoritmit on suunniteltu siten, että ne sopivat hyvin tiettyihin tietoihin.

Paul Hsieh teki kerran nopean hajautusmerkin . Hän listaa lähdekoodin ja selitykset. Mutta se oli jo lyöty. 🙂

Vastaa

Java käyttää tätä yksinkertaista kertoa -ja-lisää algoritmi:

String-objektin hajautuskoodi lasketaan nimellä

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

int-aritmeettinen, jossa s[i] on merkkijonon i ​ -merkki, n on merkkijonon pituus ja ^ osoittaa eksponentin. (Tyhjän merkkijonon hash-arvo on nolla.)

Siellä on todennäköisesti paljon parempia, mutta tämä on melko yleistä ja näyttää olevan hyvä kompromissi nopeuden ja ainutlaatuisuuden välillä.

Kommentit

  • En käytä ’ en käytä täsmälleen samaa yhtä käytettiin täällä, koska ’ on edelleen suhteellisen helppo tuottaa törmäyksiä tämän kanssa. ’ s ehdottomasti ole kauhea, mutta siellä on paljon parempia. Ja jos ’ ei ole merkittävää syytä olla yhteensopiva Javan kanssa, sitä ei pitäisi ei valita.
  • Jos valitset edelleen tämän jostain syystä voit käyttää ainakin parempaa alkua, kuten 92821, kertojana. Se vähentää törmäyksiä paljon. stackoverflow.com/a/2816747/21499
  • Voit myös käyttää FNV1a: ta. Se ’ on myös yksinkertainen kertointipohjainen hajautus, mutta käyttää suurempaa kerrointa, joka hajauttaa hajautuksen paremmin.
  • Et ’ ei halua tehdä s[0]*31^3 + s[1]*31^2 + s[2]*31 + s[3]. Vältä verkko-operaattoria (^) ja tee se näin: ((s[0]*31 + s[1])*31 + s[2])*31 + s[3].
  • @LeopoldoSanczyk Kyllä, koodissa se tehdään (ja pitäisi tehdä) iteratiivisesti, se oli vain helpompi ymmärtää suljetussa kaavassa.

Vastaus

Ensinnäkin, miksi sinun on ensin toteutettava oma hajautus? Useimmissa tehtävissä sinun pitäisi saada hyviä tuloksia tietorakenteilla tavallisesta kirjastosta olettaen, että toteutus on käytettävissä (ellet tee sitä vain oman koulusi vuoksi).

Mitä tulee todellisiin hajautusalgoritmeihin, oma suosikkini on FNV. 1

Tässä on esimerkki 32-bittisen version toteutuksesta C: ssä:

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; } 

Kommentit

  • FNV-1a-muunnos on hieman parempi satunnaisuudella. Vaihda * ja ^: h = (h * 16777619) ^ p[i] == > h = (h ^ p[i]) * 16777619

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *