Universal hashing er en type hashing , hvor der ikke bruges én specifik hashfunktion, men der foretages et valg fra en given familie efter en tilfældig algoritme [1] [2] . Denne tilgang sikrer ensartet hashing: for den næste nøgle er sandsynligheden for at placere den i en hvilken som helst celle den samme. Adskillige familier af universelle hash-funktioner er kendte og har adskillige anvendelser inden for datalogi , især i hashtabeller , probabilistiske algoritmer og kryptografi .
Begrebet universel hashing blev først introduceret i artiklen [1] af Carter og Wegman i 1979.
Oprindeligt blev universal hashing udviklet som en input-uafhængig algoritme, der kører i gennemsnit i lineær tid og er designet til at gemme og hente nøgler fra en hash-tabel. Input-uafhængighed betyder, at for enhver sekvens af input vil de tilsvarende hash-værdier for elementerne i sekvensen være jævnt fordelt over hash-tabellen. Når denne betingelse er opfyldt, viser den gennemsnitlige køretid for algoritmen for enhver data sig at være sammenlignelig med køretiden for hashfunktionen, der bruges til at distribuere kendte data [1] .
Den skabte universelle hash-algoritme var et tilfældigt udvalg af en hash-funktion fra et bestemt sæt hash-funktioner (kaldet en universel familie af hash-funktioner), der har bestemte egenskaber. Forfatterne har vist, at i tilfælde af universel hashing er antallet af hash-tabeladgange (i gennemsnit over alle funktioner fra familien) for vilkårlige inputdata meget tæt på det teoretiske minimum for tilfældet med en fast hash-funktion med tilfældigt fordelt inputdata [1] .
Ved at bruge universel hashing ønskede forfatterne [1] :
I [1] anvendte Wegman og Carter universel hashing til at bygge en hash-tabel, selvom senere universel hashing er blevet brugt i andre områder (se #Usage ).
Lad være et sæt nøgler, være et endeligt sæt af hashfunktioner, der tilknyttes sættet . Lad os tage vilkårlig og og definere kollisionsfunktionen :
Hvis , så siger vi, at der er en kollision . Du kan definere en kollisionsfunktion ikke for individuelle elementer , men for et helt sæt af elementer - for dette skal du tilføje kollisionsfunktionerne over alle elementer fra sættet. For eksempel, hvis er et sæt hash-funktioner, , , så får vi for kollisionsfunktionen :
Desuden er rækkefølgen af summeringen ligegyldig.
Definition. En familie af hash-funktioner kaldes universel [1] if
Der kan gives en anden definition, der svarer til denne.
Definition . En familie af hashfunktioner kaldes universel [3] [4] if
Følgende sætning definerer en funktions nedre grænse for en vilkårlig familie af hashfunktioner [1] .
Sætning 1. For enhver familie (ikke nødvendigvis universel) af hashfunktioner eksisterer der sådan, at
Det følger af sætning 1, at den nedre grænse for kollisionsfunktionen er tæt på i tilfældet, hvor . Faktisk er dette ofte tilfældet. Lad f.eks. compileren kortlægge tusinde variabler til sekvenser på syv engelske bogstaver. Derefter , a
For en universel familie af hashfunktioner betyder det, at de øvre og nedre grænser for kollisionsfunktionen er ret tæt på [1] .
I [1] blev universel hashing brugt til at organisere hashtabeller med kollisionsopløsning ved at kæde . Nedenfor er sætninger, der giver nogle estimater af værdierne af kollisionsfunktionen og hashing-ydelse i tilfælde af at organisere en hash-tabel med kollisionsopløsning ved hjælp af kædemetoden.
Lad være en universel familie af hash-funktioner, der knytter nøglesættet til sættet . Lad en tilfældig funktion bruges til at organisere en hash-tabel med kollisionsopløsning ved kædemetoden, det vil sige ved hjælp af en lineær liste . Hvis hash-funktionen tilknyttede et undersæt af nøgler til tabellen, vil den gennemsnitlige længde af de sammenkædede lister være . Følgende sætning giver et skøn for kollisionsfunktionen i tilfælde af en universel familie.
Sætning 2. [1] Lade være et vilkårligt element i mængden , være en vilkårlig delmængde af mængden . Lad funktionen vælges tilfældigt fra den universelle familie af hashfunktioner . Så gælder følgende skøn:
Dette resultat kan bruges til at beregne den forventede hash-ydeevne for en sekvens af forespørgsler. Men først skal vi afklare, hvad der menes med ydeevne. For at gøre dette skal du definere omkostningsbegrebet - prisen på én forespørgsel til hashtabellen for nøgle er antallet , hvor er nøglesættet tidligere placeret i tabellen, og selve hashtabellen bruger kædemetoden ( det vil sige, dette er antallet af operationer, der kræves for at fuldføre en ). Prisen for en hash-funktion på en sekvens af anmodninger er summen af omkostningerne ved de individuelle anmodninger i den sekvens, der er angivet i . Omkostninger er i bund og grund et kvantitativt mål for produktivitet.
Sætning 3. [1] Lad La være en sekvens af forespørgsler, der indeholder indsættelser. Lad være en universel familie af hash-funktioner. Så for en tilfældigt valgt hash-funktion er uligheden sand :
.
Ganske ofte [1] kendes det omtrentlige antal nøgler, der skal gemmes i en hash-tabel. Derefter kan du vælge størrelsen på hash-tabellen, så forholdet er omtrent lig med 1. Derfor, ifølge sætning 3, vil de forventede omkostninger ved at udføre en sekvens af forespørgsler være direkte proportional med antallet af forespørgsler . Desuden gælder dette for enhver sekvens af forespørgsler og ikke for en "gennemsnitlig" sekvens.
For enhver tilfældigt udvalgt hash-funktion fra den universelle familie viser dens ydeevne sig at være ganske god. Tilbage står spørgsmålet, om hashfunktionen skal ændres over tid, og i så fald hvor ofte.
I tilfælde af hashtabeller fører ændring af hashfunktioner ofte til en masse overhead. For eksempel, hvis hash-tabellen er meget stor, vil ændring af hash-funktionen kræve flytning af en stor mængde data. Der er flere strategier til at vælge en hash-funktion. Den enkleste strategi er tilfældigt at vælge en hash-funktion i begyndelsen af arbejdet og ikke ændre den før slutningen af arbejdet. I dette tilfælde er ydeevnen af hash-funktionen dog væsentligt lavere end forventet [1] . En anden strategi er at tælle antallet af kollisioner fra tid til anden og ændre hash-funktionen, hvis antallet er væsentligt højere end forventet. Denne tilgang giver god ydeevne, forudsat at hash-funktionen er valgt tilfældigt.
Dette afsnit er viet til konstruktionen af universelle familier af hashfunktioner, hvorfra en hashfunktion er tilfældigt udvalgt.
Der er flere familier af universelle hash-funktioner, der adskiller sig i, hvilke data disse funktioner er beregnet til: skalarer (talhashing), vektorer med fast længde (vektorhashing), vektorer med variabel længde (strenghashing).
Vi vælger et primtal og betragter feltet og dets multiplikationsgruppe .
Sætning. Sættet af funktioner i formen , hvor , er universel (Dette blev vist i arbejdet af Carter og Wegman [1] ).
Faktisk kun når
Hvis , så forskellen og kan vendes modulo . Herfra kan du få
Denne ligning har løsninger, og højre side kan tage værdier. Således er sandsynligheden for kollisioner
,som har tendens til at være .
Lad tallet være primtal. Lad inputdataene være repræsenteret som en sekvens af elementer, der tilhører , dvs.
For alle sekvenser af formularen skal du overveje en funktion af formularen
Lad os antage det
Det indeholder åbenbart
Sætning. Set er en generisk familie af hash-funktioner (Dette er også blevet vist af Carter og Wegman [1] ).
Faktisk, hvis , og , så hvis og kun hvis
Siden , så for hvilken den angivne ligning er opfyldt. Antallet af sådanne sekvenser er lig med , og dermed antallet af funktioner fra , som ikke skelner og også er lig med . Men hvorfra følger universaliteten.
Denne familie af funktioner kan generaliseres [5] . Overvej en familie af funktioner , og for en vektor , overvej hash-funktionen
, hvorSå vil sættet af sådanne funktioner også være en universel familie.
I dette tilfælde er input til hash-funktionen vektorer, hvis længde ikke er en fast værdi. Hvis det er muligt at begrænse længden af alle vektorer til et eller andet antal , så kan man anvende den tilgang, der blev brugt til vektorer med fast længde. I dette tilfælde, hvis længden af vektoren er mindre end , så er det muligt at supplere vektoren med nuller, så dens længde bliver lig med [5]
Antag nu, at det ikke er muligt at forudvælge et tal , der begrænser længden af alle vektorer. Så kan vi foreslå følgende fremgangsmåde [6] : lad der være en inputvektor . Lad os antage det , og vi vil betragte vektorens komponenter som koefficienterne for polynomiet : hvor .
Derefter, for vektorer med variabel længde, kan den universelle hash-funktion defineres som følger:
hvor
er en generisk hashfunktion til numeriske argumenter.
Beskedgodkendelseskoder UMAC , Poly1305-AES og nogle andre er baseret på brugen af universel hashing [7] [8] [9] . I disse koder har hver besked sin egen hash-funktion, afhængigt af dets unikke engangsnummer.
Den generiske familie af hashfunktioner kan bruges, når der kræves et stort antal "gode" hashfunktioner. Programmører bruger ofte meget tid på at analysere hash-funktioner på forskellige data og forsøge at vælge den rigtige [10] . Søgetiden kan reduceres ved at tage en universel familie af hash-funktioner og tilfældigt vælge flere funktioner fra denne familie [1] .
Den teoretiske betydning af universel hashing er, at den giver en "god" bundet til den gennemsnitlige ydeevne af algoritmer, der bruger hashing. For eksempel er universel hashing blevet anvendt i algoritmerne præsenteret i [11] [12] [13] .
I teoretisk kryptografi blev det vist, at det ved hjælp af universelle hash-funktioner er muligt at bygge et autentificeringssystem med den maksimalt opnåelige hemmeligholdelse [1] . Et eksempel på en universel hash-funktion med dokumenteret kryptografisk styrke er SWIFFT- hash-funktionen .
Desuden er en af de vigtigste anvendelser af universel hashing koordineret hentning [2] .