Универсальное хеширование

В математике и вычислительной технике универсальное хеширование рандомизированном алгоритме или структуре данных) означает случайный выбор хеш-функции из семейства хеш-функций с определенным математическим свойством (см. определение ниже). Это гарантирует низкое количество коллизий в ожидании , даже если данные выбраны злоумышленником. Известно множество универсальных семейств (для хеширования целых чисел, векторов, строк), и их оценка часто бывает очень эффективной. Универсальное хеширование имеет множество применений в информатике, например, в реализации хеш-таблиц , рандомизированных алгоритмов и криптографии .

Введение [ править ]

Предположим, мы хотим сопоставить ключи из какой-то вселенной в контейнеры (с маркировкой ). Алгоритму придется обрабатывать некоторый набор данных. из ключи, которые заранее не известны. Обычно целью хеширования является получение небольшого количества коллизий (ключи из они попадают в тот же контейнер). Детерминированная хеш-функция не может дать никаких гарантий в состязательных условиях, если , поскольку противник может выбрать быть точно прообразом мусорного ведра. Это означает, что все ключи данных попадают в один и тот же контейнер, что делает хеширование бесполезным. Более того, детерминированная хэш-функция не допускает повторного хеширования : иногда входные данные оказываются неподходящими для хеш-функции (например, слишком много коллизий), поэтому хотелось бы изменить хеш-функцию.

Решением этих проблем является случайный выбор функции из семейства хеш-функций. Семейство функций называется универсальной семьей , если .

Другими словами, любые два разных ключа Вселенной сталкиваются с вероятностью не более когда хеш-функция вытягивается равномерно случайным образом из . Это именно та вероятность коллизии, которую мы могли бы ожидать, если бы хэш-функция присваивала каждому ключу действительно случайные хэш-коды.

Иногда определение смягчается постоянным коэффициентом, требуя только вероятности столкновения. скорее, чем . Эту концепцию ввели Картер и Вегман. [1] в 1977 году и нашел многочисленные применения в информатике (см., например , [2] ) .

Если у нас есть верхняя граница о вероятности столкновения мы говорим, что имеем -почти универсальность. Так, например, универсальная семья имеет -почти универсальность.

Многие, но не все, универсальные семейства обладают следующим более сильным свойством равномерной разности :

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

Обратите внимание, что определение универсальности касается только того, является ли , который подсчитывает столкновения. Свойство равномерной разности более сильное.

(Аналогично, универсальное семейство может быть универсальным XOR, если , значение равномерно распределен в где — это побитовая исключающая операция или. Это возможно только в том случае, если это степень двойки.)

Еще более сильным условием является попарная независимость : мы имеем это свойство, когда у нас есть вероятность, что будет хэшироваться с любой парой хеш-значений как будто они были совершенно случайными: . Парную независимость иногда называют сильной универсальностью.

Еще одно свойство — однородность. Мы говорим, что семейство является однородным, если все значения хеш-функции одинаково вероятны: для любого хэш-значения . Универсальность не означает единообразия. Однако сильная универсальность предполагает единообразие.

Имея семейство со свойством равномерного расстояния, можно создать попарно независимое или сильно универсальное хеш-семейство, добавив равномерно распределенную случайную константу со значениями в к хеш-функциям. (Аналогично, если является степенью двойки, мы можем добиться попарной независимости от универсального семейства хэшей XOR, выполнив исключающую случайную константу или с равномерно распределенной случайной константой.) Поскольку сдвиг на константу иногда не имеет значения в приложениях (например, хеш-таблицах), тщательное разграничение между свойством равномерного расстояния и попарно независимым иногда не проводится. [3]

Для некоторых приложений (например, хеш-таблиц) важно, чтобы младшие биты хеш-значений также были универсальными. Когда семья строго универсальна, это гарантировано: если представляет собой сильно универсальное семейство с , то семейство, составленное из функций для всех также является сильно универсальным для . К сожалению, то же самое нельзя сказать о (просто) универсальных семьях. Например, семья, состоящая из тождественной функции явно универсален, но семейство состоит из функции не может быть универсальным.

UMAC , Poly1305-AES и некоторые другие алгоритмы кода аутентификации сообщений основаны на универсальном хешировании. [4] [5] В таких приложениях программное обеспечение выбирает новую хэш-функцию для каждого сообщения на основе уникального nonce для этого сообщения.

Некоторые реализации хеш-таблиц основаны на универсальном хешировании.В таких приложениях обычно программное обеспечение выбирает новую хэш-функцию только после того, как заметит, что произошло «слишком много» ключей; до тех пор одна и та же хеш-функция будет использоваться снова и снова.(Некоторые схемы разрешения коллизий, такие как динамическое идеальное хеширование , выбирают новую хэш-функцию каждый раз, когда происходит коллизия. Другие схемы разрешения коллизий, такие как хеширование с кукушкой и хеширование с двумя вариантами , допускают несколько коллизий, прежде чем выбрать новую хеш-функцию. ). Обзор самых быстрых известных универсальных и сильно универсальных хэш-функций для целых чисел, векторов истроки находятся в. [6]

гарантии Математические

Для любого фиксированного набора из ключей, использование универсального семейства гарантирует следующие свойства.

  1. Для любого фиксированного в , ожидаемое количество ключей в корзине является . При реализации хеш-таблиц путем объединения это число пропорционально ожидаемому времени выполнения операции с использованием ключа. (например, запрос, вставка или удаление).
  2. Ожидаемое количество пар ключей в с которые сталкиваются ( ) ограничено сверху , что в порядке . Когда количество бункеров, выбирается линейным по (т.е. определяется функцией из ), ожидаемое количество столкновений равно . При хешировании в бункеров, коллизий вообще нет с вероятностью не менее половины.
  3. Ожидаемое количество ключей в корзинах не менее ключи в них ограничены сверху . [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]

  1. Человек выбирает главное быть близким к степени двойки, например простому числу Мерсенна . Это позволяет выполнять арифметические операции по модулю быть реализовано без деления (с использованием более быстрых операций, таких как сложение и сдвиг). Например, в современных архитектурах можно работать с , пока 's - 32-битные значения.
  2. К блокам можно применять векторное хеширование. Например, векторное хеширование применяется к каждому блоку строки из 16 слов, а хеширование строки применяется к результаты. Поскольку более медленное хеширование строк применяется к значительно меньшему вектору, оно, по сути, будет таким же быстрым, как и векторное хеширование.
  3. В качестве делителя выбирают степень двойки, что позволяет выполнять арифметические операции по модулю. реализовать без деления (с использованием более быстрых операций битовой маскировки ). Семейство хеш-функций NH использует этот подход.

См. также [ править ]

Ссылки [ править ]

  1. Перейти обратно: Перейти обратно: а б с д и Картер, Ларри; Вегман, Марк Н. (1979). «Универсальные классы хэш-функций» . Журнал компьютерных и системных наук . 18 (2): 143–154. дои : 10.1016/0022-0000(79)90044-8 . Конференц-версия в STOC'77.
  2. ^ Мильтерсен, Питер Бро. «Универсальное хеширование» (PDF) . Архивировано из оригинала (PDF) 24 мая 2011 года . Проверено 24 июня 2009 г.
  3. ^ Мотвани, Раджив; Рагхаван, Прабхакар (1995). Рандомизированные алгоритмы . Издательство Кембриджского университета. п. 221. ИСБН  0-521-47465-5 .
  4. ^ Дэвид Вагнер, изд. «Достижения криптологии — КРИПТО 2008» .п. 145.
  5. ^ Жан-Филипп Омассон, Вилли Мейер, Рафаэль Фан, Лука Хенцен. «Хеш-функция BLAKE» .2014.п. 10.
  6. ^ Торуп, Миккель (2015). «Высокоскоростное хеширование целых и строк». arXiv : 1504.06804 [ cs.DS ].
  7. Перейти обратно: Перейти обратно: а б Баран, Илия; Демейн, Эрик Д.; Патрашку, Михай (2008). «Подквадратичные алгоритмы для 3SUM» (PDF) . Алгоритмика . 50 (4): 584–596. дои : 10.1007/s00453-007-9036-3 . S2CID   9855995 .
  8. ^ Дитцфельбингер, Мартин; Хагеруп, Торбен; Катахайнен, Юрки; Пенттонен, Мартти (1997). «Надежный рандомизированный алгоритм решения задачи ближайшей пары» (Постскриптум) . Журнал алгоритмов . 25 (1): 19–51. дои : 10.1006/jagm.1997.0873 . Проверено 10 февраля 2011 г.
  9. ^ Торуп, Миккель (18 декабря 2009 г.). «Алгоритмы из учебника SODA» .
  10. ^ Вельфель, Филипп (1999). Эффективное сильно универсальное и оптимально универсальное хеширование . Математические основы информатики 1999. LNCS. Том. 1672. стр. 262–272. дои : 10.1007/3-540-48340-3_24 .
  11. Перейти обратно: Перейти обратно: а б с д Торуп, Миккель (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
  12. Перейти обратно: Перейти обратно: а б Дитцфельбингер, Мартин; Гил, Джозеф; Матиас, Йоси; Пиппенджер, Николас (1992). Полиномиальные хэш-функции надежны (расширенное резюме) . Учеб. 19-й Международный коллоквиум по автоматам, языкам и программированию (ICALP) . стр. 235–246.
  13. ^ Блэк, Дж.; Халеви, С.; Кравчик, Х.; Кровец, Т. (1999). UMAC: Быстрая и безопасная аутентификация сообщений (PDF) . Достижения в криптологии (CRYPTO '99) . , Уравнение 1
  14. ^ Патрашку, Михай ; Торуп, Миккель (2011). Возможности простого хеширования таблиц . Материалы 43-го ежегодного симпозиума ACM по теории вычислений (STOC '11) . стр. 1–10. arXiv : 1011.5200 . дои : 10.1145/1993636.1993638 . ISBN  9781450306911 .
  15. Перейти обратно: Перейти обратно: а б Касер, Оуэн; Лемир, Дэниел (2013). «Строго универсальное хеширование строк происходит быстро». Компьютерный журнал . 57 (11). Издательство Оксфордского университета: 1624–1638. arXiv : 1202.4961 . дои : 10.1093/comjnl/bxt070 .
  16. ^ «Слайды курса еврейского университета» (PDF) .
  17. ^ Роберт Узгалис. «Библиотечные хэш-функции» .1996.
  18. ^ Канковск, Питер. «Хеш-функции: эмпирическое сравнение» .
  19. ^ Йигит, Озан. «Строковые хеш-функции» .
  20. ^ Керниган; Ричи (1988). «6» . Язык программирования C (2-е изд.). Прентис Холл. стр. 118 . ISBN  0-13-110362-8 . {{cite book}}: CS1 maint: несколько имен: список авторов ( ссылка )
  21. ^ «Строка (платформа Java SE 6)» . docs.oracle.com . Проверено 10 июня 2015 г.

Дальнейшее чтение [ править ]

Внешние ссылки [ править ]