Hashing mit Linearer Suche (Linear Probing)

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