Универсальное хеширование
В математике и вычислительной технике универсальное хеширование (в рандомизированном алгоритме или структуре данных) означает случайный выбор хеш-функции из семейства хеш-функций с определенным математическим свойством (см. определение ниже). Это гарантирует низкое количество коллизий в ожидании , даже если данные выбраны злоумышленником. Известно множество универсальных семейств (для хеширования целых чисел, векторов, строк), и их оценка часто бывает очень эффективной. Универсальное хеширование имеет множество применений в информатике, например, в реализации хеш-таблиц , рандомизированных алгоритмов и криптографии .
Введение
[ редактировать ]Предположим, мы хотим сопоставить ключи из какой-то вселенной в контейнеры (с маркировкой ). Алгоритму придется обрабатывать некоторый набор данных. из ключи, которые заранее не известны. Обычно целью хеширования является получение небольшого количества коллизий (ключи из они попадают в тот же контейнер). Детерминированная хеш-функция не может дать никаких гарантий в состязательных условиях, если , поскольку противник может выбрать быть точно прообразом мусорного ведра. Это означает, что все ключи данных попадают в один и тот же контейнер, что делает хеширование бесполезным. Более того, детерминированная хэш-функция не допускает повторного хеширования : иногда входные данные оказываются неподходящими для хеш-функции (например, слишком много коллизий), поэтому хотелось бы изменить хеш-функцию.
Решением этих проблем является случайный выбор функции из семейства хеш-функций. Семейство функций называется универсальной семьей , если .
Другими словами, любые два разных ключа Вселенной сталкиваются с вероятностью не более когда хеш-функция вытягивается равномерно случайным образом из . Это именно та вероятность коллизии, которую мы могли бы ожидать, если бы хэш-функция присваивала каждому ключу действительно случайные хэш-коды.
Иногда определение смягчается постоянным коэффициентом, требуя только вероятности столкновения. скорее, чем . Эту концепцию ввели Картер и Вегман. [1] в 1977 году и нашел многочисленные применения в информатике (см., например , [2] ) .
Если у нас есть верхняя граница о вероятности столкновения мы говорим, что имеем -почти универсальность. Так, например, универсальная семья имеет -почти универсальность.
Многие, но не все, универсальные семейства обладают следующим более сильным свойством равномерной разности :
- , когда выбирается случайным образом из семьи , разница равномерно распределен в .
Обратите внимание, что определение универсальности касается только того, является ли , который подсчитывает столкновения. Свойство равномерной разности более сильное.
(Аналогично, универсальное семейство может быть универсальным XOR, если , значение равномерно распределен в где — это побитовая исключающая операция или. Это возможно только в том случае, если это степень двойки.)
Еще более сильным условием является попарная независимость : мы имеем это свойство, когда у нас есть вероятность, что будет хэшироваться с любой парой хеш-значений как будто они были совершенно случайными: . Парную независимость иногда называют сильной универсальностью.
Еще одно свойство — однородность. Мы говорим, что семейство является однородным, если все значения хеш-функции одинаково вероятны: для любого хэш-значения . Универсальность не означает единообразия. Однако сильная универсальность предполагает единообразие.
Имея семейство со свойством равномерного расстояния, можно создать попарно независимое или сильно универсальное хеш-семейство, добавив равномерно распределенную случайную константу со значениями в к хеш-функциям. (Аналогично, если является степенью двойки, мы можем добиться попарной независимости от универсального семейства хэшей XOR, выполнив исключающую случайную константу или с равномерно распределенной случайной константой.) Поскольку сдвиг на константу иногда не имеет значения в приложениях (например, хэш-таблицах), тщательное разграничение между свойством равномерного расстояния и попарно независимым иногда не проводится. [3]
Для некоторых приложений (например, хеш-таблиц) важно, чтобы младшие биты хеш-значений также были универсальными. Когда семья строго универсальна, это гарантировано: если представляет собой сильно универсальное семейство с , то семейство, составленное из функций для всех также является сильно универсальным для . К сожалению, то же самое нельзя сказать о (просто) универсальных семьях. Например, семья, состоящая из тождественной функции явно универсален, но семейство, состоящее из функции не может быть универсальным.
UMAC , Poly1305-AES и некоторые другие алгоритмы кода аутентификации сообщений основаны на универсальном хешировании. [4] [5] В таких приложениях программное обеспечение выбирает новую хэш-функцию для каждого сообщения на основе уникального nonce для этого сообщения.
Некоторые реализации хеш-таблиц основаны на универсальном хешировании. В таких приложениях обычно программное обеспечение выбирает новую хэш-функцию только после того, как заметит, что произошло «слишком много» ключей; до тех пор одна и та же хэш-функция будет использоваться снова и снова. (Некоторые схемы разрешения коллизий, такие как динамическое идеальное хеширование , выбирают новую хеш-функцию каждый раз, когда происходит коллизия. Другие схемы разрешения коллизий, такие как хеширование с кукушкой и хеширование с двумя вариантами , допускают несколько коллизий, прежде чем выбрать новую хеш-функцию. ). Обзор самых быстрых известных универсальных и сильно универсальных хеш-функций для целых чисел, векторов и строки находятся в. [6]
Математические гарантии
[ редактировать ]Для любого фиксированного набора из ключей, использование универсального семейства гарантирует следующие свойства.
- Для любого фиксированного в , ожидаемое количество ключей в корзине является . При реализации хеш-таблиц путем объединения это число пропорционально ожидаемому времени выполнения операции с использованием ключа. (например, запрос, вставка или удаление).
- Ожидаемое количество пар ключей в с которые сталкиваются ( ) ограничено сверху , что в порядке . Когда количество бункеров, выбирается линейным по (т.е. определяется функцией из ), ожидаемое количество столкновений равно . При хешировании в бункеров, коллизий вообще нет с вероятностью не менее половины.
- Ожидаемое количество ключей в корзинах не менее ключи в них ограничены сверху . [7] Таким образом, если вместимость каждого контейнера ограничена трехкратным средним размером ( ), общее количество ключей в переполненных бункерах не более . Это справедливо только для семейства хэшей, вероятность коллизии которого ограничена сверху величиной . Если используется более слабое определение, ограничивая его формулой , этот результат уже не соответствует действительности. [7]
Поскольку приведенные выше гарантии справедливы для любого фиксированного набора , они сохраняются, если набор данных выбран противником. Однако злоумышленник должен сделать этот выбор до (или независимо от) случайного выбора алгоритмом хэш-функции. Если злоумышленник может наблюдать за случайным выбором алгоритма, случайность бесполезна, и ситуация аналогична детерминированному хешированию.
Вторая и третья гарантии обычно используются вместе с перефразированием . Например, можно подготовить рандомизированный алгоритм для обработки некоторых количество столкновений. Если он наблюдает слишком много столкновений, он выбирает другое случайное из семьи и повторяется. Универсальность гарантирует, что количество повторений является геометрической случайной величиной .
Конструкции
[ редактировать ]Поскольку любые компьютерные данные могут быть представлены в виде одного или нескольких машинных слов, обычно требуются хэш-функции для трех типов областей: машинные слова («целые числа»); векторы машинных слов фиксированной длины; и векторы переменной длины («строки»).
Хеширование целых чисел
[ редактировать ]В этом разделе рассматривается случай хеширования целых чисел, которые помещаются в машинные слова; таким образом, такие операции, как умножение, сложение, деление и т. д., являются дешевыми инструкциями машинного уровня. Пусть вселенная, которую нужно хэшировать, будет .
Оригинальное предложение Картера и Вегмана [1] было выбрать простое число и определить
где являются случайно выбранными целыми числами по модулю с . (Это одна итерация линейного конгруэнтного генератора .)
Чтобы увидеть это является универсальным семейством, заметим, что имеет место только тогда, когда
для некоторого целого числа между и . С , если их разница ненулевое значение и имеет обратный по модулю . Решение для урожайность
- .
Есть возможные варианты для (с исключено) и, варьируя в допустимом диапазоне, возможные ненулевые значения для правой части. Таким образом, вероятность столкновения равна
- .
Еще один способ увидеть является универсальной семьей через понятие статистического расстояния . Напишите разницу как
- .
С ненулевое значение и равномерно распределен в , отсюда следует, что модуль также равномерно распределены в . Распределение таким образом, почти однороден, вплоть до разницы в вероятности между образцами. В результате статистическое расстояние до однородного семейства равно , который становится пренебрежимо малым, когда .
Семейство более простых хеш-функций
является лишь приблизительно универсальным: для всех . [1] Более того, этот анализ почти точен; Картер и Вегман [1] покажи это в любое время .
Как избежать модульной арифметики
[ редактировать ]Современным способом хеширования целых чисел является схема с множественным сдвигом, описанная Дитцфельбингером и др. в 1997 году. [8] Избегая модульной арифметики, этот метод гораздо проще реализовать, а также на практике он работает значительно быстрее (обычно как минимум в четыре раза). [9] ). Схема предполагает, что количество ячеек равно степени двойки, . Позволять — количество битов в машинном слове. Затем хеш-функции параметризуются по нечетным положительным целым числам. (что подходит под одно слово биты). Чтобы оценить , умножить к модуль и затем поддерживать высокий порядок бит в качестве хеш-кода. В математической записи это
Эта схема не удовлетворяет свойству равномерной разности и является лишь -почти универсальный ; для любого , .
Чтобы понять поведение хеш-функции, обратите внимание, что если и имеют одинаковые старшие биты «M», тогда имеет либо все 1, либо все 0 в качестве битов M высшего порядка (в зависимости от того, или больше). Предположим, что младший бит набора появляется на позиции . С является случайным нечетным целым числом, а нечетные целые числа имеют обратные значения в кольце , отсюда следует, что будут равномерно распределены между -битовые целые числа с младшим установленным битом в позиции . Таким образом, вероятность того, что все эти биты равны 0 или 1, не превышает . С другой стороны, если , то M бит более высокого порядка содержат как 0, так и 1, поэтому это точно, что . Наконец, если затем немного из равен 1 и тогда и только тогда, когда биты также равны 1, что происходит с вероятностью .
Этот анализ является точным, как можно показать на примере и . Чтобы получить действительно «универсальную» хеш-функцию, можно использовать схему «умножить-сложить-сдвиг», которая выбирает биты более высокого порядка.
где представляет собой случайное положительное целое число с и представляет собой случайное неотрицательное целое число с . Для этого необходимо выполнить арифметические действия -битные беззнаковые целые числа. Эта версия множественного сдвига принадлежит Дитцфельбингеру и позже была более точно проанализирована Вельфелем. [10]
Хеширование векторов
[ редактировать ]В этом разделе рассматривается хеширование вектора машинных слов фиксированной длины. Интерпретируйте ввод как вектор из машинные слова (целые числа бит каждый). Если — универсальное семейство со свойством равномерной разности, следующее семейство (восходящее к Картеру и Вегману) [1] ) также обладает свойством равномерной разности (и, следовательно, является универсальным):
- , где каждый выбирается независимо случайным образом.
Если является степенью двойки, то суммирование можно заменить исключающим или. [11]
На практике, если доступна арифметика двойной точности, она реализуется с помощью семейства хэш-функций с умноженным сдвигом. [12] Инициализируйте хэш-функцию с помощью вектора случайных нечетных целых чисел на бит каждый. Тогда, если количество ячеек равно для :
- .
Можно сократить вдвое количество умножений, что на практике примерно означает двукратное ускорение. [11] Инициализируйте хэш-функцию с помощью вектора случайных нечетных целых чисел на бит каждый. Следующее семейство хешей является универсальным: [13]
- .
Если операции двойной точности недоступны, можно интерпретировать входные данные как вектор полуслов ( -битовые целые числа). Затем алгоритм будет использовать умножения, где было число полуслов в векторе. Таким образом, алгоритм работает со «скоростью» одного умножения на входное слово.
Эту же схему можно использовать и для хеширования целых чисел, интерпретируя их биты как векторы байтов. В этом варианте векторный метод известен как табулационное хеширование и представляет собой практическую альтернативу схемам универсального хеширования на основе умножения. [14]
Также возможна сильная универсальность на высокой скорости. [15] Инициализируйте хэш-функцию с помощью вектора случайных целых чисел на биты. Вычислить
- .
Результат является строго универсальным на биты. Экспериментально было обнаружено, что на последних процессорах Intel он работает со скоростью 0,2 цикла ЦП на байт. .
Хеширование строк
[ редактировать ]Это относится к хешированию переменного размера вектора машинных слов . Если длина строки может быть ограничена небольшим числом, лучше всего использовать векторное решение сверху (концептуально дополняя вектор нулями до верхней границы). Требуемое пространство — это максимальная длина строки, но время для вычисления это всего лишь длина . Поскольку нули в строке запрещены, заполнение нулями можно игнорировать при вычислении хеш-функции, не влияя на универсальность. [11] Обратите внимание: если в строке разрешены нули, то лучше всего перед заполнением добавить ко всем строкам фиктивный ненулевой символ (например, 1): это гарантирует, что универсальность не пострадает. [15]
Теперь предположим, что мы хотим хешировать , где хорошая привязка априори не известно. Универсальная семья, предложенная [12] обрабатывает строку как коэффициенты многочлена по модулю большого простого числа. Если , позволять быть простым и определить:
- , где является равномерно случайным и выбирается случайным образом из целочисленной области отображения универсального семейства .
Используя свойства модульной арифметики, приведенное выше можно вычислить без создания больших чисел для больших строк следующим образом: [16]
uint hash(String x, int a, int p)
uint h = INITIAL_VALUE
for (uint i=0 ; i < x.length ; ++i)
h = ((h*a) + x[i]) mod p
return h
Этот скользящий хэш Рабина-Карпа основан на линейном конгруэнтном генераторе . [17] Вышеуказанный алгоритм также известен как мультипликативная хеш-функция . [18] На практике оператора mod и параметра p можно вообще избежать, просто разрешив переполнение целого числа, поскольку оно эквивалентно mod ( Max-Int-Value + 1) во многих языках программирования. В таблице ниже показаны значения, выбранные для инициализации h и a для некоторых популярных реализаций.
Выполнение | INITIAL_VALUE | а |
---|---|---|
Бернштейна Хэш-функция djb2 [19] | 5381 | 33 |
СТЛПорт 4.6.2 | 0 | 5 |
Кернигана и Ритчи Хэш-функция [20] | 0 | 31 |
java.lang.String.hashCode() [21]
|
0 | 31 |
Рассмотрим две строки и пусть быть длиной более длинного; для анализа более короткая строка концептуально дополняется нулями до длины . Столкновение перед применением подразумевает, что является корнем многочлена с коэффициентами . Этот полином имеет не более корни по модулю , поэтому вероятность столкновения не более . Вероятность столкновения через случайное приводит общую вероятность столкновения к . Таким образом, если простое число достаточно велико по сравнению с длиной хешируемых строк, семейство очень близко к универсальному (по статистическому расстоянию ).
Другие универсальные семейства хеш-функций, используемые для хеширования строк неизвестной длины до хэш-значений фиксированной длины, включают отпечаток Рабина и Бужаш .
Как избежать модульной арифметики
[ редактировать ]Чтобы смягчить вычислительные издержки модульной арифметики, на практике используются три приема: [11]
- Человек выбирает главное быть близким к степени двойки, например простому числу Мерсенна . Это позволяет выполнять арифметические операции по модулю быть реализовано без деления (с использованием более быстрых операций, таких как сложение и сдвиг). Например, в современных архитектурах можно работать с , пока 's - 32-битные значения.
- К блокам можно применять векторное хеширование. Например, векторное хеширование применяется к каждому блоку строки из 16 слов, а хеширование строки применяется к результаты. Поскольку более медленное хеширование строк применяется к значительно меньшему вектору, оно, по сути, будет таким же быстрым, как и векторное хеширование.
- В качестве делителя выбирают степень двойки, что позволяет выполнять арифметические операции по модулю. реализовать без деления (с использованием более быстрых операций битовой маскировки ). Семейство хеш-функций NH использует этот подход.
См. также
[ редактировать ]- K-независимое хеширование - семейство хэш-функций
- Прокручивающееся хеширование — тип хеш-функции.
- Табулационное хеширование – хэш-функции, вычисляемые методом исключающего или
- Минимальная независимость — метод интеллектуального анализа данных.
- Универсальная односторонняя хеш-функция - тип универсальной хеш-функции в криптографии, предложенный в качестве альтернативы устойчивым к коллизиям хеш-функциям.
- Последовательность с низким расхождением - Тип математической последовательности
- Идеальное хеширование – хеш-функция без каких-либо коллизий.
Ссылки
[ редактировать ]- ^ Jump up to: а б с д и Картер, Ларри; Вегман, Марк Н. (1979). «Универсальные классы хэш-функций» . Журнал компьютерных и системных наук . 18 (2): 143–154. дои : 10.1016/0022-0000(79)90044-8 . Конференц-версия в STOC'77.
- ^ Мильтерсен, Питер Бро. «Универсальное хеширование» (PDF) . Архивировано из оригинала (PDF) 24 мая 2011 года . Проверено 24 июня 2009 г.
- ^ Мотвани, Раджив; Рагхаван, Прабхакар (1995). Рандомизированные алгоритмы . Издательство Кембриджского университета. п. 221. ИСБН 0-521-47465-5 .
- ^ Дэвид Вагнер, изд. «Достижения криптологии — КРИПТО 2008» . п. 145.
- ^ Жан-Филипп Омассон, Вилли Мейер, Рафаэль Фан, Лука Хенцен. «Хеш-функция BLAKE» . 2014. п. 10.
- ^ Торуп, Миккель (2015). «Высокоскоростное хеширование целых и строк». arXiv : 1504.06804 [ cs.DS ].
- ^ Jump up to: а б Баран, Илия; Демейн, Эрик Д.; Патрашку, Михай (2008). «Подквадратичные алгоритмы для 3SUM» (PDF) . Алгоритмика . 50 (4): 584–596. дои : 10.1007/s00453-007-9036-3 . S2CID 9855995 .
- ^ Дитцфельбингер, Мартин; Хагеруп, Торбен; Катахайнен, Юрки; Пенттонен, Мартти (1997). «Надежный рандомизированный алгоритм решения задачи ближайшей пары» (Постскриптум) . Журнал алгоритмов . 25 (1): 19–51. дои : 10.1006/jagm.1997.0873 . Проверено 10 февраля 2011 г.
- ^ Торуп, Миккель (18 декабря 2009 г.). «Алгоритмы из учебника SODA» .
- ^ Вельфель, Филипп (1999). Эффективное сильно универсальное и оптимально универсальное хеширование . Математические основы информатики 1999. LNCS. Том. 1672. стр. 262–272. дои : 10.1007/3-540-48340-3_24 .
- ^ Jump up to: а б с д Торуп, Миккель (2009). Хеширование строк для линейного зондирования . Учеб. 20-й симпозиум ACM-SIAM по дискретным алгоритмам (SODA) . стр. 655–664. CiteSeerX 10.1.1.215.4253 . дои : 10.1137/1.9781611973068.72 . ISBN 978-0-89871-680-1 . , раздел 5.3
- ^ Jump up to: а б Дитцфельбингер, Мартин; Гил, Джозеф; Матиас, Йоси; Пиппенджер, Николас (1992). Полиномиальные хеш-функции надежны (расширенное резюме) . Учеб. 19-й Международный коллоквиум по автоматам, языкам и программированию (ICALP) . стр. 235–246.
- ^ Блэк, Дж.; Халеви, С.; Кравчик, Х.; Кровец, Т. (1999). UMAC: Быстрая и безопасная аутентификация сообщений (PDF) . Достижения в криптологии (CRYPTO '99) . , Уравнение 1
- ^ Патрашку, Михай ; Торуп, Миккель (2011). Возможности простого хеширования таблиц . Материалы 43-го ежегодного симпозиума ACM по теории вычислений (STOC '11) . стр. 1–10. arXiv : 1011.5200 . дои : 10.1145/1993636.1993638 . ISBN 9781450306911 .
- ^ Jump up to: а б Касер, Оуэн; Лемир, Дэниел (2013). «Строго универсальное хеширование строк происходит быстро». Компьютерный журнал . 57 (11). Издательство Оксфордского университета: 1624–1638. arXiv : 1202.4961 . дои : 10.1093/comjnl/bxt070 .
- ^ «Слайды курса еврейского университета» (PDF) .
- ^ Роберт Узгалис. «Библиотечные хэш-функции» . 1996.
- ^ Канковск, Питер. «Хеш-функции: эмпирическое сравнение» .
- ^ Йигит, Озан. «Строковые хеш-функции» .
- ^ Керниган; Ричи (1988). «6» . Язык программирования C (2-е изд.). Прентис Холл. стр. 118 . ISBN 0-13-110362-8 .
{{cite book}}
: CS1 maint: несколько имен: список авторов ( ссылка ) - ^ «Строка (платформа Java SE 6)» . docs.oracle.com . Проверено 10 июня 2015 г.
Дальнейшее чтение
[ редактировать ]- Кнут, Дональд Эрвин (1998). Искусство компьютерного программирования, Том. III: Сортировка и поиск (3-е изд.). Чтение, месса; Лондон: Аддисон-Уэсли. ISBN 0-201-89685-0 .