Hashing mit Linearer Suche (Linear Probing) Zurück zur Ursprungsidee. Elemente werden direkt in der Tabelle gespeichert. Kollisionen werden durch Finden anderer Stellen aufgelöst. linear probing: Suche nächsten freien Platz. h Am Ende fange von vorn an. I einfach I platz-ezient I cache-ezient M t 155 Der einfache Teil Class m, m0 : N; h : Key → 0..m − 1) t =[⊥, . . . , ⊥] : Array [0..m + m0 − 1] of Element invariant ∀i : t [i ] 6= ⊥ ⇒ ∀j ∈ {h(t [i ])..i − 1} : t [j ] 6= ⊥ BoundedLinearProbing( Procedure insert(e : Element) for (i := h(e ); t [i ] 6= ⊥; i ++ ) assert i < m + m0 − 1 h ; m t [i ] := e Function nd(k : Key) : Element for (i := h(k ); t [i ] 6= ⊥; i ++ ) if t [i ] = k then return t [i ] return ⊥ M t m’ 156 Remove Beispiel: t = [. . . , x , y , z , . . .], h(z ) x) remove( invariant ∀i : t [i ] 6= ⊥ ⇒ ∀j ∈ {h(t [i ])..i − 1} : t [j ] 6= ⊥ Procedure remove(k : Key) for (i := h(k ); k 6= t [i ]; i ++ ) // search k if t [i ] = ⊥ then return // nothing to do // we plan for a hole at i . for (j := i + 1; t [j ] 6= ⊥; j ++ ) // Establish invariant for t [j ]. if h(t [j ]) ≤ i then t [i ] := t [j ] // Overwrite removed element i := j // move planned hole t [i ] := ⊥ // erase freed entry 157 an tt 0 insert : axe, chop, clip, cube, dice, fell, hack, hash, lop, slash bo cp dq er fs gt hu iv jw kx 1 5 7 9 10 2 3 4 6 8 axe chop axe chop clip axe chop clip axe cube chop clip axe cube dice ly 11 chop chop chop chop clip clip clip clip axe axe axe axe cube cube cube cube dice dice dice hash dice hash lop hack fell fell fell fell chop clip axe cube dice hash lop slash hack fell hash lop slash hack hash lop slash hack hash slash slash hack hash slash hack fell fell fell fell remove chop chop chop chop clip lop lop lop axe axe axe axe cube cube cube cube hack mz 12 clip dice dice dice dice 158 Verketten ↔ Lineare Suche Volllaufen: Verketten weniger empndlich. Unbeschränktes Hashing mit lin. Suche hat nur amortisiert konst. Einfügezeit Cache: Lineare Suche besser. Vor allem für doall Platz/Zeit Abwägung: Kompliziert! Abhängig von n, Füllgrad, Elementgröÿe, Implementierungsdetails bei Verketten (shared dummy!, t speichert Zeiger oder item), Speicherverwaltung bei Verketten, beschränkt oder nicht,. . . Referentielle Integrität: Nur bei Verketten ! Leistungsgarantien: Universelles Hashing funktioniert so nur mit Verketten 159 Perfektes Hashing hier nicht 160 Mehr Hashing I Hohe Wahrscheinlichkeit, Garantien für den schlechtesten Fall, Garantien für linear probing höhere Anforderungen an die Hash-Funktionen I Hashing als Mittel zur Lastverteilung z. B., storage servers, (peer to peer Netze,. . . ) I O(1) nd / perfektes Hashing 161 Hashtabellen für assoziative Arrays I In Java: java.util.Hashtable, in Python: dict I Beispiel (Python): args["username"]="fred" (CGI-Skripte) I Beispiel für Sicherheitsproblem: I Webserver beantwortet HTTP-Anfragen mit Python-Skript I HTTP-Parameter werden für Skript in dict eingelesen I Problem: Hashfunktion h deterministisch (d.h. fest, bekannt!) I Bösartige Anfrage: viele HTTP-Parameter x =y mit gleichem h(x ) I Konsequenz: dict wird zur Liste, quadratischer Aufwand bei Einlesen/Verarbeiten von Skriptparametern → Denial of Service I Wie reparieren? 162 Kryptographische Hashfunktionen I Universelle Hashfunktionen: kurze Ausgabe (typisch: ≤ 32 Bit), Kollisionen gleichmäÿig I Kryptographische Hashfunktionen: längere Ausgabe (typisch: 128512 Bit), Kollisionen existieren, sind aber schwer zu nden I Anwendungen: I Fingerabdruck von groÿen Datenmengen I Zertikate (z.B. für Webserver) I Nutzerauthentikation (Unix: /etc/passwd) I Beispiele: MD5 (unsicher), SHA-1 (unsicher), SHA-256, SHA-3 I Mehr in Sicherheits-Vorlesung 163
© Copyright 2024