Rullaava hash

Rolling hash ( eng.  rolling hash , myös ring hash ) on hash-funktio , joka käsittelee syötteen tietyssä ikkunassa. Hajautusarvon saaminen siirretylle ikkunalle tällaisissa funktioissa on halpa toimenpide. Arvon uudelleen laskemiseksi sinun tarvitsee vain tietää edellinen hash-arvo, ikkunan ulkopuolelle jääneiden syöttötietojen arvo ja ikkunaan pudonneiden tietojen arvo. Toisin sanoen, jos on sekvenssin tiiviste , niin "siirretyn" sekvenssin tiiviste voidaan saada käyttämällä helposti laskettavaa funktiota .

Mahdollisuus nopeasti "siirtää" hashia asettaa joitain rajoituksia teoreettisille takuille. Erityisesti on osoitettu [1] , että rengastiivisteiden perheet eivät voi olla 3-riippumattomia ; maksimi - universaali tai 2-riippumaton . Useimmissa sovelluksissa universaalisuus (jopa likimääräinen) on kuitenkin riittävä.

Ring hashia käytetään etsimään alimerkkijonoa Rabin-Karp- algoritmissa , laskemaan N- grammien tiivisteitä tekstistä [2] ja myös rsync -ohjelmassa vertailemaan binääritiedostoja (käytetään adler-32 rengasversiota ) .

Polynomi hash

Rabin - Karp-algoritmi käyttää usein yksinkertaista polynomirengastiivistettä, joka perustuu kerto- ja yhteenlaskuoperaatioihin [3] [4] :

.

Mielivaltaisen tarkkuuden kokonaislukuaritmeettisen käytön välttämiseksi käytetään jäännösrengasaritmetiikkaa modulo , joka sopii yhteen konesanaan . Vakioiden valinta on erittäin tärkeä laadukkaan tiivisteen saamiseksi. Hajautuksen alkuperäisessä versiossa oletettiin, että sen pitäisi olla satunnaisesti valittu alkuluku ja . [3] Mutta koska algoritmi satunnaisen alkuluvun valitsemiseksi ei ole niin yksinkertainen, he käyttävät mieluummin hash-varianttia, jossa on kiinteä alkuluku, mutta joka valitaan satunnaisesti alueelta . Dietzfelbinger ym. [4] osoittivat, että tällä hash-versiolla on samat teoreettiset ominaisuudet kuin alkuperäisellä. Erityisesti todennäköisyys, että kahden eri merkkijonon ja ja hajautusarvot eivät ylitä , if ja ovat kokonaislukuja alueelta , ja valitaan todella satunnaisesti.

Vanhojen syöttösymbolien poistaminen ja uusien lisääminen tehdään lisäämällä tai vähentämällä kaavan ensimmäinen tai viimeinen termi (modulo ). Jäsenen poistamiseksi tallennetaan ennalta laskettu arvo . Ikkunaa siirretään kertomalla koko polynomi tai jakamalla ( jos se on yksinkertainen, niin jäännösrenkaassa on mahdollista kertoa käänteisluvulla jakamisen sijaan). Käytännössä on kätevintä olettaa 32- ja 64-bittisiä konesanoja (nämä ovat ns. Mersennen alkulukuja ). Siinä tapauksessa modulo-operaatio voidaan suorittaa monilla tietokoneilla käyttämällä nopeita bittikohtaisia ​​siirto- ja summaustoimintoja [5] . Toinen mahdollinen vaihtoehto on arvot tai , joille on olemassa myös nopeita algoritmeja jaon loppuosan ottamiseksi (tässä tapauksessa hyväksyttävien arvojen alue on hieman kaventunut) [6] . Yleinen väärinkäsitys on uskoa . On olemassa merkkijonoperheitä, joissa hash c tuottaa aina monia törmäyksiä valinnasta riippumatta . [7] Nämä ja muut toteutusyksityiskohdat ja polynomin hashin teoreettinen analyysi löytyvät Rabin-Karp-algoritmia käsittelevästä julkaisusta .

Polynomi hash yli GF(2 L )

Tämä hash on samanlainen kuin tavallinen polynomitiiviste, mutta kaikki sen laskelmat suoritetaan viimeisessä kentässä . Yleensä asetetaan arvoon 64. Kenttäelementit ovat numeroita . Kentän yhteenlasku toteutetaan käyttämällä bittikohtaista poissulkevaa "tai" -toimintoa ja kertolasku suoritetaan operaatiolla , joka ensin ei-siirrettävästi kertoo : llä ja ottaa sitten loppuosan tuloksen "ei-siirrettävästä" jaosta. jollakin valitulla kiinteällä elementillä (tässä ei-siirrettävä jako on operaatio käänteinen ei-siirrettävälle kertolaskulle). Elementti on valittava siten, että ja on pelkistymätön polynomi kentän yli (kenttää pidetään usein kentän yli olevien polynomien joukkona modulo mielivaltaisen asteisen redusoitumattoman polynomin joukoksi ). Voit esimerkiksi laittaa [8] . Sitten hash lasketaan seuraavasti [4] :

,

jossa on satunnaisesti valittu luku tiivisteen alustusvaiheessa alueelta , ja se on lyhyt merkintä missä toistuvia kertoja. Algebran peruslauseen avulla voidaan osoittaa, että kahden eripituisen merkkijonon tiivistystörmäyksen todennäköisyys ei ylitä . On osoitettu [8] , että nykyaikaisissa Intel- ja AMD -prosessoreissa kaikki hajautusarvon edellyttämä kentän aritmetiikka voidaan laskea tehokkaasti käyttämällä CLMUL -laajennuksen ohjeita .

Hash syklisten polynomien mukaan (Buzhash)

Olkoon  jokin hash, joka yhdistää tiivistetyn merkkijonon merkit -bittisiksi numeroiksi (yleensä tai ). Hajautus syklisten polynomien avulla määritellään seuraavasti [2] :

jossa  on bittikohtaisesti poissulkeva "tai" -operaatio ja  operaatio bittiluvun syklisestä siirrosta bitti kerrallaan vasemmalle. On helppo osoittaa, että tämä hash on pyöreä:

Tämän hashin tärkein etu on, että se käyttää vain nopeita bittikohtaisia ​​toimintoja, jotka ovat saatavilla monissa nykyaikaisissa tietokoneissa. Hajautuksen laatu riippuu suoraan funktion valinnasta . Lemire ja Cacer [1] osoittivat, että jos funktio valitaan satunnaisesti riippumattomien tiivistefunktioiden perheestä , niin kahden eripituisen merkkijonon tiivisteiden yhteensopivuuden todennäköisyys ei ylitä . Tämä asettaa tiettyjä rajoituksia tehtäville, joissa tätä tiivistettä voidaan käyttää. Ensinnäkin tiivistettävien merkkijonojen pituuden on oltava pienempi kuin . Yleiskäyttöisissä hajautusalgoritmeissa tämä ehto voi olla ongelma, mutta esimerkiksi hajautusalgoritmissa -grams , jossa ei yleensä ylitä 16, tällainen rajoitus on luonnollinen ( -grammien tapauksessa tekstin yksittäiset merkit toistavat hahmojen rooli). Toiseksi itsenäisten toimintojen perheen valinta voi myös olla ongelma joissain tapauksissa. Tavuaakkostossa funktioperheellä, joka on koodattu 256 eri satunnaisbittiluvun taulukolla, on riippumattomuusominaisuus (funktion valinta on taulukon täyttäminen). Hashing -grammeja varten voit antaa eri tokeneille erilaisia ​​satunnaisia ​​-bittinumeroita (yleensä eri merkkien määrä tällaisissa ongelmissa on suhteellisen pieni), ja tällaisella hash-funktioiden perheellä on myös itsenäisyyden ominaisuus.

Rabinin hash

Tämä tiiviste on sovellettavissa vain siinä erikoistapauksessa, jossa tiivistetyn merkkijonon merkit ovat numerot 0 ja 1. Hajautuksen ideana on tarkastella syötemerkkijonoa polynomina kentän päällä ja itse hash ottaa loput jaosta satunnaisesti valitulla hashilla alustusvaiheessa redusoitumaton astepolynomi kentän yli . Tämä on pohjimmiltaan sama menettely kuin CRC :ssä . Tarkastellaanpa sitä tarkemmin.

Merkkijonon hajautustulos on bittijono . Numero valitaan yksinkertainen [9] ja riittävän suuri, mutta niin, että sekvenssi mahtuu yhteen konesanaan (yleensä ota tai [9] ). Olkoon jokin redusoitumaton astepolynomi kentän yli . Merkitään vastaavalla numerolla bittimuodolla . Hash-funktio määritellään luvuksi, jolla on bittimuotoinen esitys siten, että polynomi on polynomin polynomilla jakamisen jäännös , eli .

Melko hämmentävästä määritelmästä huolimatta Rabin-hash on melko helppo toteuttaa (jos redusoitumaton polynomi on jo löydetty). Laskelmat perustuvat tällaiseen yksinkertaiseen havaintoon: jos luku , jossa on bittiesitys, koodaa polynomin , niin luku koodaa polynomin , jossa tarkoittaa operaatiota , jossa numero yksi bitti siirretään bittittäin vasemmalle siten, että vähiten merkitsevä bitti korvataan nollalla ( ei pidä sekoittaa edellä määriteltyyn sykliseen siirtoon!). Antaa , ja  olla bitin esitys . Sitten se lasketaan seuraavasti:

jos jos

Hash on pyöreä. Antaa ja  olla bitin esitys . Hash lasketaan seuraavasti [9] :

jos jos

jossa  on bittiluku, jonka bittiesitys vastaa polynomia . Luku lasketaan etukäteen alustattaessa pituisen merkkijonon tiivistettä .

Suurin vaikeus on valita satunnaisesti redusoitumaton astepolynomi . Rabin [9] kuvasi tehokkaan algoritmin tämän tekemiseen ja osoitti, että kahden eripituisen merkkijonon hash-törmäyksen todennäköisyys satunnaisella valinnalla ei ylitä .

Huomaa, että tämä hash sekoitetaan usein polynomitiivisteeseen samanlaisen laajuuden, polynomien huomioimisen ja yhteisen tekijän vuoksi.

Linkit

Muistiinpanot

  1. 12 Lemire , Kaser, 2010 .
  2. 12 Cohen , 1997 .
  3. 1 2 Rabin, Karp, 1987 .
  4. 1 2 3 Dietzfelbinger, Gil, Matias, Pippinger, 1992 .
  5. SE Anderson. Hieman hämmentäviä hakkereita. Arkistoitu 1. kesäkuuta 2020 Wayback Machinessa
  6. Krovetz, Rogaway, 2000 .
  7. Pachocki, Radoszewski, 2013 .
  8. 12. Lemire , Kaser, 2016 .
  9. 1 2 3 4 Rabin, 1981 .

Kirjallisuus