Hašovací tabulka je jedním z typů nástrojů pro ukládání informací. V informatice se těmto nástrojům pro uchovávání informací nebo dat říká datové struktury. Hašovací tabulka je datová struktura, která používá hašovací funkci pro určení místa uložení dat. Každá informace, která má být uložena, má své jméno, které se nazývá klíč. Klíčem může být například jméno osoby. Ke každému klíči je přiřazena nějaká hodnota, například telefonní číslo osoby nebo jiná data.

Data jsou uložena v další datové struktuře zvané pole, což si lze představit jako řadu políček (slotů). Každé pole má index (číslo) počínaje zpravidla 0. Myšlenkou hašovací tabulky je pomocí klíče rychle spočítat, do kterého indexu pole pár klíč–hodnota uložit. K tomu slouží hašovací funkce, která z klíče vrátí (nebo mapuje na) číslo indexu.

Jak hašovací tabulka funguje

Jednoduchý postup vkládání a vyhledávání v hašovací tabulce:

  • Vložení: spočítáme haš pomocí klíče (hašovací funkce) a výsledné číslo upravíme na velikost pole (např. modulo jeho délky). Do příslušného slotu uložíme pár klíč/hodnota.
  • Vyhledání: stejným způsobem z klíče spočítáme index a v daném slotu hledáme odpovídající klíč; pokud ho najdeme, vrátíme hodnotu.
  • Odstranění: najdeme položku přes haš a klíč a prvek odstraníme nebo označíme jako smazaný.

Praktická hašovací funkce by měla být rychlá, rovnoměrně rozdělovat klíče do slotů a minimalizovat kolize (situace, kdy různé klíče dávají stejný index).

Kolize a jejich řešení

Kolize jsou nevyhnutelnou součástí hašovacích tabulek. Existují dvě běžné strategie jejich řešení:

  • Oddělené řetězení (chaining) – v každém slotu pole je seznam (např. spojový seznam nebo dynamické pole) položek, které se mapují do stejného indexu. Při kolizi se nová položka přidá do seznamu.
  • Otevřené adresování (open addressing) – pokud je slot obsazen, hledá se další volný slot podle pevného pravidla (probíhá „prohledávání“ tabulky). Mezi strategie patří lineární prohledávání (linear probing), kvadratické prohledávání (quadratic probing) nebo dvojité hašování (double hashing).

Výkonnost a složitost

Hašovací tabulky jsou populární díky velmi dobré průměrné časové náročnosti:

  • Průměrná složitost operací (vložení, vyhledání, smazání): O(1).
  • Někdy (v nejhorším případě, např. mnoho kolizí nebo špatná hašovací funkce) může být složitost O(n), kde n je počet prvků.

Klíčovým parametrem je load factor (využití tabulky) α = počet prvků / počet slotů. Při vysokém α roste pravděpodobnost kolizí, proto se tabulka obvykle zvětšuje (resizing) — vytvoří se větší pole a existující položky se znovu hashují do nové tabulky.

Použití hašovacích tabulek

Díky rychlému přístupu se hašovací tabulky běžně používají v mnoha částech softwaru:

  • asociativní pole a slovníky (key-value store),
  • implementace databází a indexů,
  • mezipaměti (cache),
  • implementace množin (set),
  • symbolické tabulky v překladačích,
  • detekce duplicit, agregace dat a další.

Praktické poznámky a bezpečnost

  • Ne všechny hašovací funkce jsou vhodné. Pro běžné tabulky se používají rychlé, nekryptografické hašovací funkce, které rovnoměrně rozdělují klíče. Kryptografické hashy (např. SHA-256) jsou pomalejší a obvykle se nepoužívají pro běžné hašovací tabulky.
  • Pro citlivá použití (např. ukládání hesel) se používají speciální kryptografické techniky a „key derivation“ funkce (bcrypt, scrypt, Argon2), protože hesla se neukládají do hašovacích tabulek stejným způsobem jako běžná data.
  • Útočník může způsobit zahlcení hašovací tabulky (hash flooding) tím, že zašle mnoho klíčů produkujících kolize; některé implementace proto používají bezpečnější hašovací funkce nebo náhodné solení haše při initializaci tabulky.

Implementační tipy

  • Volba velikosti pole: často se volí velikost jako prvočíslo nebo mocnina dvou (v závislosti na použité hašovací strategii) pro lepší rozložení.
  • Při odděleném řetězení je dobré používat dynamické seznamy, u otevřeného adresování dbát na korektní zpracování smazaných slotů.
  • Pravidelně monitorujte load factor a automaticky zvyšujte (a případně snižujte) velikost tabulky pro udržení dobré výkonnosti.

Příklad jednoduché hašovací funkce pro řetězce

Jednoduchý a ilustrační postup: součet kódů znaků modulo velikost pole. Tento postup je jednoduchý, ale často vede ke špatnému rozložení a není doporučen pro reálné nasazení. Lepší jsou prověřené algoritmy jako MurmurHash nebo FNV pro nekryptografické účely.

Závěr

Hašovací tabulka je velmi užitečná datová struktura pro rychlý přístup k datům podle klíče. Její efektivita závisí především na kvalitě hašovací funkce, způsobu řešení kolizí a správném řízení load factoru. Díky těmto vlastnostem se hašovací tabulky široce používají v programování i v databázích.