- •Введение
- •Хеширование
- •Разрешение коллизий методом цепочек.
- •Разрешение коллизий "открытой адресацией".
- •Квадратичная и произвольная адресация
- •Удаление элементов хеш-таблицы
- •Применение хеширования
- •Хеширование паролей
- •Сравнение методов.
- •Функции bCrypt.
- •Общие сведения о криптографии
- •Шифрование с закрытым ключом
- •Шифрование с открытым ключом
- •Электронная цифровая подпись
- •Генерация случайных чисел.
- •Использование генератора псевдослучайных чисел
- •Криптография и защита информации.
- •Заключение
- •Список литературы:
Разрешение коллизий методом цепочек.
Мы уже говорили, что некоторые адреса могут порождаться несколькими ключами. Пожалуй, наиболее очевидный способ решения проблемы состоит в том, чтобы поддерживать M связанных списков, по одному на каждый возможный хеш-адрес. Все записи должны содержать поля LINK; кроме того, нужно иметь M головных узлов списков HEAD[i], где i меняется от 1 до M. После хеширования
HEAD[1]: [__] [ TO ][ ] [ FIRE ][ Λ ]
HEAD[2]: [__] [ SYV ][ Λ ]
HEAD[3]: [__] [ EN ][ Λ ]
HEAD[4]: [__] [ TRE ][ Λ ]
HEAD[5]: [__] [ FEM ][ Λ ]
HEAD[6]: [_Λ_]
HEAD[7]: [_Λ_]
HEAD[8]: [_Λ ]
HEAD[9]: [__] [ SEKS ][ Λ ]
Рис. 1. Раздельные цепочки.
ключа мы просто выполняем последовательный поиск в списке с номером h(K)+1.
Рисунок иллюстрирует этот простой метод цепочек при M=9для последовательности семи ключей
K=|EN|, |TO|, |TRE|, |FIRE|, |FEM|, |SEKS|, |SYV|
(так называются числа от 1 до 7 по-норвежски), имеющих соответственные хеш-коды
h(K)+1 = 3, 1, 4, 1, 5, 9, 2.
Первый список содержит два элемента, три списка пусты.
Метод цепочек является весьма быстрым, поскольку списки коротки. Если в одной комнате собрать 365 человек, то найдется много пар, имеющих один и тот же день рождения, но данный день рождения в среднем имеет лишь один человек! Вообще, если имеется N ключей и M списков, средний размер списка равен N/M; таким образом, хеширование уменьшает количество работы, требуемое на последовательный поиск, примерно в M раз.
В целях экономии времени желательны большие M , но в этом случае многие ссылки будут пустыми, так что большая часть пространства, отводимого под M головных узлов, потратится зря. Для небольших по размеру записей напрашивается другой подход: можно наложить пространство для записей на пространство для головных узлов, отводя в таблице место под M записей и M ссылок, а не под N записей и M+N ссылок.
Иногда можно совершить один проход по данным и выяснить, какие головные узлы будут использоваться, вставляя на следующем проходе "переполняющие" записи в свободные щели. Часто, однако, это нежелательно или невозможно; нам хотелось бы иметь метод, при котором каждая запись обрабатывается лишь один раз, при первом поступлении в систему. Следующий алгоритм, принадлежащий Ф.Уильямсу, является общепринятым способом решения этой задачи.
alg C. (Поиск с вставкой по рассеянной таблице с цепочками.)
Предлагаемый алгоритм позволяет отыскать в таблице из M элементов данный ключ K.
Если K нет в таблице и она не полна, K вставляется в нее.
Элементы таблицы обозначаются через TABLE[i], 0≤i≤ M, и могут быть двух различных типов: свободный и занятый. Занятый узел содержит ключевое поле KEY[i], поле ссылки LINK[i] и, возможно, другие поля.
Алгоритм использует хеш-функцию h(K). Для облегчения поиска свободного пространства используется вспомогательная переменная R; если таблица пуста, R=M+1; по мере проведения вставок будет оставаться в силе утверждение, что узлы TABLE|[j] заняты для всех j в диапазоне R≤j≤M.
Условимся, что узел TABLE[0] всегда будет свободен.
C1. [Хеширование.] Установить i←h(K)+1. (Теперь 1≤i≤M.)
C2. [Список?] Если узел TABLE[i] свободен, то перейти на C6.
(В противном случае этот узел занят, и мы последуем на имеющийся здесь список занятых узлов).
C3. [Сравнение.] Если K=KEY[i], поиск завершен удачно.
C4. [Переход к следующему.] Если LINK[i]≠0, установить i←LINK[i] и вернуться на C3.
C5. [Найти свободный узел.] (Поиск был неудачным, и мы хотим найти в таблице свободное место.) Уменьшать R до тех пор, пока не будет получено такое значение, что узел TABLE[R] свободен.
Если R=0, алгоритм заканчивается по переполнению (свободных узлов больше нет); в противном случае установить LINK[i]←R, i←R.
C6. [Вставить новый ключ.] Пометить TABLE[i] как занятый узел С KEY[i]←K и LINK[i]←0.
В алгоритме допускается срастание нескольких списков, так что после вставки в таблицу записи перемещать не нужно.
Рис. 2. Поиск с вставкой по рассеянной таблице с цепочками.
TABLE[1]: [ TO ][ ]
TABLE[2]: [ SYV ][ Λ ]
TABLE[3]: [ EN ][ Λ ]
TABLE[4]: [ TRE ][ Λ ]
TABLE[5]: [ FEM ][ Λ ]
TABLE[6]: [_ Λ _]
TABLE[7]: [_ Λ _]
TABLE[8]: [ SEKS ][ Λ ]
TABLE[9]: [ FIRE ][ ]
рис. 3. Сросшиеся списки.
На первый взгляд шаг C5 может показаться неэффективным, так как в нем поиск свободной позиции производится последовательно. Но в действительности в процессе заполнения таблицы суммарное число проб в шаге C5 не превышает количества элементов в таблице; значит, в среднем на каждую вставку тратится не более одной такой пробы!