Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курсовая работа - Язык С++, хеширование (Подбильский, Кнут).docx
Скачиваний:
42
Добавлен:
27.06.2018
Размер:
1.12 Mб
Скачать

Хеширование

Хеширование(англ.hashing) — преобразованиемассивавходных данных произвольной длины в (выходную)битовуюстроку фиксированной длины, выполняемоеопределённым алгоритмом. Функция, реализующая алгоритм и выполняющая преобразование, называется «хеш-функцией» или «функцией свёртки». Исходные данные называются входным массивом, «ключом» или «сообщением». Результат преобразования (выходные данные) называется «хешем», «хеш-кодом», «хеш-суммой», «сводкойсообщения».

Хеширование применяется в следующих случаях:

  • при построении ассоциативных массивов;

  • при поиске дубликатов в сериях наборов данных;

  • при построении уникальных идентификаторов для наборов данных;

  • при вычислении контрольных сумм от данных (сигнала) для последующего обнаружения в них ошибок (возникших случайно или внесённых намеренно), возникающих при хранении и/или передаче данных;

  • при сохранении паролей в системах защиты в виде хеш-кода (для восстановления пароля по хеш-коду требуется функция, являющаяся обратной по отношению к использованной хеш-функции);

  • при выработке электронной подписи (на практике часто подписывается не само сообщение, а его «хеш-образ»);

  • и др.

В общем случае (согласно принципу Дирихле) нет однозначного соответствия между исходными (входными) данными и хеш-кодом (выходными данными). Возвращаемые хеш-функцией значения (выходные данные) менее разнообразны, чем значения входного массива (входные данные). Случай, при котором хеш-функция преобразует несколько разных сообщений в одинаковые сводки называется «коллизией». Вероятность возникновения коллизий используется для оценки качества хеш-функций.

Существует множество алгоритмов хеширования, отличающихся различными свойствами. Примеры свойств:

  • разрядность;

  • вычислительная сложность;

  • криптостойкость.

Выбор той или иной хеш-функции определяется спецификой решаемой задачи. Простейшим примером хеш-функции может служить «обрамление» данных циклическим избыточным кодом(англ.CRC,cyclic redundancy code).

Определение хэша и его вычисление

Один из лучших способов определить хэш-функцию от строки S следующий:

h(S) = S[0] + S[1] * P + S[2] * P^2 + S[3] * P^3 + ... + S[N] * P^N

где P - некоторое число.

Разумно выбирать для P простое число, примерно равное количеству символов во входном алфавите. Например, если строки предполаются состоящими только из маленьких латинских букв, то хорошим выбором будет P = 31. Если буквы могут быть и заглавными, и маленькими, то, например, можно P = 53.

Во всех кусках кода в этой статье будет использоваться P = 31.

Само значение хэша желательно хранить в самом большом числовом типе - int64, он же long long. Очевидно, что при длине строки порядка 20 символов уже будет происходить переполнение значение. Ключевой момент - что мы не обращаем внимание на эти переполнения, как бы беря хэш по модулю 2^64.

Пример вычисления хэша, если допустимы только маленькие латинские буквы:

const int p = 31;

long long hash = 0, p_pow = 1;

for (size_t i=0; i<s.length(); ++i)

{

// желательно отнимать 'a' от кода буквы

// единицу прибавляем, чтобы у строки вида 'aaaaa' хэш был ненулевой

hash += (s[i] - 'a' + 1) * p_pow;

p_pow *= p;

}

В большинстве задач имеет смысл сначала вычислить все нужные степени P в каком-либо массиве.