1. 1
  2. 2
  3. 3
  4. 4
  5. 5

# конспект · шаг 5 из 5

Конспект: универсальное и идеальное хеширование

выжимка - её можно унести в заметки

Понятия

Атака на фиксированную функцию (HashDoS) - зная публичную хеш-функцию, противник подбирает ключи с одним h(k), валит их в одну ячейку, и операции становятся O(n). Реально клали веб-сервисы горстью подобранных параметров.

Универсальное хеширование - берут СЕМЕЙСТВО функций H и выбирают СЛУЧАЙНУЮ при создании таблицы (случайность в тайных параметрах, например a, b). Семейство универсально, если Pr[h(k₁) = h(k₂)] ≤ 1/m для любых k₁ ≠ k₂ (по выбору h). Даёт ожидаемую длину цепочки 1 + α на ЛЮБОМ входе: враг знает семейство, но не выбранную функцию. Это O(1) в ОЖИДАНИИ, не гарантия. Годится для ДИНАМИЧЕСКОГО набора.

Идеальное хеширование - O(1) в ХУДШЕМ случае и память O(n), но только для СТАТИЧНОГО набора (известен заранее). Два уровня: - уровень 1: универсальная функция раскидывает n ключей по n корзинам (коллизии есть); - уровень 2: корзину из kⱼ ключей кладут во вторичную таблицу размером kⱼ² со своей функцией БЕЗ коллизий.

Размер k² - из парадокса дней рождения наоборот: при m = k² ожидаемых коллизий ≈ 1/2, бескризисную функцию находят за пару попыток. Сумма Σ kⱼ² = O(n) (универсальная верхняя функция не создаёт больших корзин).

Что унести

Два инструмента под два условия - и общий принцип «гарантии покупаются знанием о входе».

универсальное идеальное
гарантия O(1) в ОЖИДАНИИ O(1) в ХУДШЕМ случае
набор ключей динамический статичный (заранее известен)
механизм случайная функция из семейства два уровня, вторичка k²
защищает от подобранного врагом входа (даёт железную скорость)
применение словари языков (соль хеша) ключевые слова, gperf

Универсальное хеширование - это тот же приём, что рандомизация опорного в выборе k-го: детерминированный алгоритм уязвим к подобранному входу → добавь случайность ВНУТРЬ, и источник неудачи переедет с данных (их контролирует враг) на монетку (её контролируешь ты). Поэтому языки солят хеш строк случайным семенем при старте (Python PYTHONHASHSEED) - hash("...") меняется между запусками, и это защита, а не баг.

Идеальное хеширование показывает вторую мысль: чем больше знаешь о входе ЗАРАНЕЕ (набор статичен), тем сильнее гарантию можно выжать (O(1) в худшем, а не только в среднем). Тот же мотив, что «знаешь диапазон ключей - сортируешь за линию».

Ловушки джокера

Фиксированная публичная функция для недоверенного входа (HTTP-параметры, имена от пользователя). Открыт путь к HashDoS. Нужна соль/универсальное хеширование.

Выбор случайной функции на КАЖДУЮ операцию. Один ключ попадёт в разные ячейки - не найдёшь. Функция выбирается ОДИН раз при создании.

«Универсальное = гарантия в худшем случае». Нет, это ОЖИДАНИЕ. Гарантию даёт идеальное (для статики).

Идеальное хеширование для динамического набора. Добавление ключа ломает бескризисность, нужна перестройка. Только статика.

Вторичная таблица размером k вместо k². Коллизии вернутся (α = 1). Нужен квадрат.

Испуг «память O(n²)». При универсальной верхней функции Σ kⱼ² = O(n); не повезло - перевыбрать функцию.

Проверь себя

Почему фиксированную функцию можно атаковать и что такое HashDoS?

Что такое универсальное семейство (определение через Pr ≤ 1/m) и почему оно защищает даже знающего семейство врага?

Чем «ожидаемо O(1)» отличается от «гарантированно O(1)»?

Как устроены два уровня идеального хеширования и почему второй берут размером k²?

Почему суммарная память идеального хеширования O(n), а не O(n²)?

Комментарии

Пока нет комментариев. Будь первым!

Оставить комментарий

Комментарий появится после проверки. Email не публикуется. Войти, чтобы не вводить имя каждый раз.