Что такое хэш функция: как это работает и где применяется

Содержание

Криптография Хеш-функции — CoderLessons.com

Хеш-функции чрезвычайно полезны и появляются практически во всех приложениях информационной безопасности.

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

Значения, возвращаемые хэш-функцией, называются дайджестом сообщения или просто хэш-значениями . На следующем рисунке проиллюстрирована хеш-функция —

Особенности хеш-функций

Типичные особенности хеш-функций —

Выход фиксированной длины (значение хэша)

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

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

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

Хеш-функция с n-битным выходом называется n-битной хеш-функцией . Популярные хеш-функции генерируют значения от 160 до 512 бит.

Эффективность операции

Обычно для любой хеш-функции h с входом x вычисление h (x) является быстрой операцией.

Вычислительные хеш-функции намного быстрее, чем симметричное шифрование.

Свойства хеш-функций

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

  • Сопротивление до изображения

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

    • Другими словами, если хеш-функция h создала хеш-значение z, то будет трудно найти любое входное значение x, которое хэширует к z.

    • Это свойство защищает от злоумышленника, который имеет только хэш-значение и пытается найти входные данные.

  • Сопротивление второго изображения

    • Это свойство означает, что заданы входные данные и их хэш, должно быть трудно найти другой входной файл с тем же хешем.

    • Другими словами, если хеш-функция h для входа x создает хеш-значение h (x), то должно быть трудно найти любое другое входное значение y такое, что h (y) = h (x).

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

  • Сопротивление столкновению

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

    • Другими словами, для хеш-функции h трудно найти любые два различных входа x и y, для которых h (x) = h (y).

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

    • Это свойство очень мешает злоумышленнику найти два входных значения с одинаковым хешем.

    • Кроме того, если хеш-функция устойчива к столкновениям, она является второй устойчивой к изображениям.

Сопротивление до изображения

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

Другими словами, если хеш-функция h создала хеш-значение z, то будет трудно найти любое входное значение x, которое хэширует к z.

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

Сопротивление второго изображения

Это свойство означает, что заданы входные данные и их хэш, должно быть трудно найти другой входной файл с тем же хешем.

Другими словами, если хеш-функция h для входа x создает хеш-значение h (x), то должно быть трудно найти любое другое входное значение y такое, что h (y) = h (x).

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

Сопротивление столкновению

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

Другими словами, для хеш-функции h трудно найти любые два различных входа x и y, для которых h (x) = h (y).

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

Это свойство очень мешает злоумышленнику найти два входных значения с одинаковым хешем.

Кроме того, если хеш-функция устойчива к столкновениям, она является второй устойчивой к изображениям.

Разработка алгоритмов хеширования

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

Размер каждого блока данных варьируется в зависимости от алгоритма. Обычно размеры блоков составляют от 128 до 512 бит. Следующая иллюстрация демонстрирует хэш-функцию —

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

Этот процесс повторяется столько раз, сколько требуется для хеширования всего сообщения. Схема алгоритма хеширования изображена на следующей иллюстрации —

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

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

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

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

Популярные хэш-функции

Давайте кратко рассмотрим некоторые популярные хеш-функции —

Дайджест сообщения (MD)

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

  • Семейство MD состоит из хеш-функций MD2, MD4, MD5 и MD6. Он был принят как Интернет-стандарт RFC 1321. Это 128-битная хеш-функция.

  • Дайджесты MD5 широко используются в мире программного обеспечения для обеспечения целостности передаваемого файла. Например, файловые серверы часто предоставляют предварительно вычисленную контрольную сумму MD5 для файлов, чтобы пользователь мог сравнить с ней контрольную сумму загруженного файла.

  • В 2004 году столкновения были обнаружены в MD5. Сообщалось, что аналитическая атака была успешной только через час с использованием компьютерного кластера. Эта атака столкновения привела к взлому MD5 и, следовательно, больше не рекомендуется для использования.

Семейство MD состоит из хеш-функций MD2, MD4, MD5 и MD6. Он был принят как Интернет-стандарт RFC 1321. Это 128-битная хеш-функция.

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

В 2004 году столкновения были обнаружены в MD5. Сообщалось, что аналитическая атака была успешной только через час с использованием компьютерного кластера. Эта атака столкновения привела к взлому MD5 и, следовательно, больше не рекомендуется для использования.

Безопасная хеш-функция (SHA)

Семейство SHA состоит из четырех алгоритмов SHA; SHA-0, SHA-1, SHA-2 и SHA-3. Хотя из одной семьи, есть структурно разные.

  • Первоначальная версия — SHA-0, 160-битная хеш-функция, была опубликована Национальным институтом стандартов и технологий (NIST) в 1993 году. Она имела несколько слабых мест и не стала очень популярной. Позднее, в 1995 году, SHA-1 был разработан для исправления предполагаемых недостатков SHA-0.

  • SHA-1 является наиболее широко используемым из существующих хеш-функций SHA. Он используется в нескольких широко используемых приложениях и протоколах, включая протокол Secure Socket Layer (SSL).

  • В 2005 году был найден метод для выявления коллизий для SHA-1 в течение практического периода времени, что делает долгосрочную возможность использования SHA-1 сомнительной.

  • Семейство SHA-2 имеет еще четыре варианта SHA: SHA-224, SHA-256, SHA-384 и SHA-512 в зависимости от количества бит в их хэш-значении. О хэш-функции SHA-2 пока не сообщалось об успешных атаках.

  • Хотя SHA-2 — сильная хеш-функция. Хотя существенно отличается, его базовый дизайн все еще следует за дизайном SHA-1. Следовательно, NIST призвал к созданию новых конкурентоспособных конструкций хэш-функций.

  • В октябре 2012 года NIST выбрал алгоритм Keccak в качестве нового стандарта SHA-3. Keccak предлагает множество преимуществ, таких как эффективная производительность и хорошая устойчивость к атакам.

Первоначальная версия — SHA-0, 160-битная хеш-функция, была опубликована Национальным институтом стандартов и технологий (NIST) в 1993 году. Она имела несколько слабых мест и не стала очень популярной. Позднее, в 1995 году, SHA-1 был разработан для исправления предполагаемых недостатков SHA-0.

SHA-1 является наиболее широко используемым из существующих хеш-функций SHA. Он используется в нескольких широко используемых приложениях и протоколах, включая протокол Secure Socket Layer (SSL).

В 2005 году был найден метод для выявления коллизий для SHA-1 в течение практического периода времени, что делает долгосрочную возможность использования SHA-1 сомнительной.

Семейство SHA-2 имеет еще четыре варианта SHA: SHA-224, SHA-256, SHA-384 и SHA-512 в зависимости от количества бит в их хэш-значении. О хэш-функции SHA-2 пока не сообщалось об успешных атаках.

Хотя SHA-2 — сильная хеш-функция. Хотя существенно отличается, его базовый дизайн все еще следует за дизайном SHA-1. Следовательно, NIST призвал к созданию новых конкурентоспособных конструкций хэш-функций.

В октябре 2012 года NIST выбрал алгоритм Keccak в качестве нового стандарта SHA-3. Keccak предлагает множество преимуществ, таких как эффективная производительность и хорошая устойчивость к атакам.

RIPEMD

RIPEND — это аббревиатура для дайджеста сообщения оценки примитивов RACE. Этот набор хеш-функций был разработан открытым исследовательским сообществом и широко известен как семейство европейских хеш-функций.

  • В комплект входят RIPEND, RIPEMD-128 и RIPEMD-160. Также существуют 256 и 320-битные версии этого алгоритма.

  • Оригинальный RIPEMD (128 бит) основан на принципах проектирования, используемых в MD4 и обеспечивает сомнительную безопасность. 128-разрядная версия RIPEMD пришла в качестве быстрой замены для устранения уязвимостей в оригинальной версии RIPEMD.

  • RIPEMD-160 является улучшенной версией и наиболее широко используемой версией в семействе. 256 и 320-битные версии снижают вероятность случайного столкновения, но не имеют более высокого уровня безопасности по сравнению с RIPEMD-128 и RIPEMD-160 соответственно.

В комплект входят RIPEND, RIPEMD-128 и RIPEMD-160. Также существуют 256 и 320-битные версии этого алгоритма.

Оригинальный RIPEMD (128 бит) основан на принципах проектирования, используемых в MD4 и обеспечивает сомнительную безопасность. 128-разрядная версия RIPEMD пришла в качестве быстрой замены для устранения уязвимостей в оригинальной версии RIPEMD.

RIPEMD-160 является улучшенной версией и наиболее широко используемой версией в семействе. 256 и 320-битные версии снижают вероятность случайного столкновения, но не имеют более высокого уровня безопасности по сравнению с RIPEMD-128 и RIPEMD-160 соответственно.

джакузи

Это 512-битная хеш-функция.

  • Он взят из модифицированной версии Advanced Encryption Standard (AES). Одним из дизайнеров был Винсент Раймен, один из создателей AES.

  • Три версии Whirlpool были выпущены; а именно, WHIRLPOOL-0, WHIRLPOOL-T и WHIRLPOOL.

Он взят из модифицированной версии Advanced Encryption Standard (AES). Одним из дизайнеров был Винсент Раймен, один из создателей AES.

Три версии Whirlpool были выпущены; а именно, WHIRLPOOL-0, WHIRLPOOL-T и WHIRLPOOL.

Применение хеш-функций

Существует два непосредственных применения хеш-функции на основе ее криптографических свойств.

Хранение пароля

Хэш-функции обеспечивают защиту для хранения паролей.

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

  • Файл паролей состоит из таблицы пар в форме (идентификатор пользователя, h (P)).

  • Процесс входа изображен на следующей иллюстрации —

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

Файл паролей состоит из таблицы пар в форме (идентификатор пользователя, h (P)).

Процесс входа изображен на следующей иллюстрации —

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

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

Проверка целостности данных

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

Процесс изображен на следующей иллюстрации —

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

НОУ ИНТУИТ | Лекция | Криптографические хеш-функции

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

Цель лекции: познакомиться с понятием «хеш-функция», а также с принципами работы таких функций.

Понятие хеш-функции

Хеш-функцией (hash function) называется математическая или иная функция, которая для строки произвольной длины вычисляет некоторое целое значение или некоторую другую строку фиксированной длины. Математически это можно записать так:

где М – исходное сообщение, называемое иногда прообразом, а h – результат, называемый значением хеш-функции (а также хеш-кодом или дайджестом сообщения (от англ. message digest )).

Смысл хеш-функции состоит в определении характерного признака прообраза – значения хеш-функции. Это значение обычно имеет определенный фиксированный размер, например, 64 или 128 бит. Хеш-код может быть в дальнейшем проанализирован для решения какой-либо задачи. Так, например, хеширование может применяться для сравнения данных: если у двух массивов данных хеш-коды разные, массивы гарантированно различаются; если одинаковые — массивы, скорее всего, одинаковы. В общем случае однозначного соответствия между исходными данными и хеш-кодом нет из-за того, что количество значений хеш-функций всегда меньше, чем вариантов входных данных. Следовательно, существует множество входных сообщений, дающих одинаковые хеш-коды (такие ситуации называются коллизиями ). Вероятность возникновения коллизий играет немаловажную роль в оценке качества хеш-функций.

Хеш-функции широко применяются в современной криптографии.

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

Например, пусть исходное сообщение, переведенное в цифровой вид, было следующим (в шестнадцатеричном формате):

Переведем сообщение в двоичный вид, запишем байты друг под другом и сложим биты в каждом столбике по модулю 2:

0011 1110
0101 0100
1010 0000
0001 1111
1101 0100
----------
0110 0101

Результат ( 0110 0101(2) или 65(16) ) и будет значением хеш-функции.

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

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

Сформулируем основные требования, предъявляемые к криптографическим хеш-функциям:

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

Создать хеш-функцию, которая удовлетворяет всем перечисленным требованиям – задача непростая. Необходимо также помнить, что на вход функции поступают данные произвольного размера, а хеш-результат не должен получаться одинаковым для данных разного размера.

В настоящее время на практике в качестве хеш-функций применяются функции, обрабатывающие входное сообщение блок за блоком и вычисляющие хеш-значение hi для каждого блока Mi входного сообщения по зависимостям вида

где hi-1 – результат, полученный при вычислении хеш-функции для предыдущего блока входных данных.

В результате выход хеш-функции hn является функцией от всех n блоков входного сообщения.

Использование блочных алгоритмов шифрования для формирования хеш-функции

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

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

  • практически невозможно без знания ключа шифрования вычисление хеш-значения для заданного открытого массива информации;
  • практически невозможен без знания ключа шифрования подбор открытых данных под заданное значение хеш-функции.

Сформированное таким образом хеш-значение обычно называют имитовставкой или аутентификатором и используется для проверки целостности сообщения. Таким образом, имитовставка – это контрольная комбинация, зависящая от открытых данных и секретной ключевой информации. Целью использования имитовставки является обнаружение всех случайных или преднамеренных изменений в массиве информации. Значение, полученное хеш-функцией при обработке входного сообщения, присоединяется к сообщению в тот момент, когда известно, что сообщение корректно. Получатель проверяет целостность сообщения путем вычисления имитовставки полученного сообщения и сравнения его с полученным хеш-кодом, который должен быть передан безопасным способом. Одним из таких безопасных способов может быть шифрование имитовставки закрытым ключом отправителя, т.е. создание подписи. Возможно также шифрование полученного хеш-кода алгоритмом симметричного шифрования, если отправитель и получатель имеют общий ключ симметричного шифрования.

Указанный процесс получения и использования имитовставки описан в отечественном стандарте ГОСТ 28147-89. Стандарт предлагает использовать младшие 32 бита блока, полученного на выходе операции шифрования всего сообщения в режиме сцепления блоков шифра для контроля целостности передаваемого сообщения. Таким же образом для формирования имитовставки можно использовать любой блочный алгоритм симметричного шифрования.

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

Таким образом, если обычную схему шифрования сообщения М с помощью блочного шифра f на ключе К мы записывали как E=f(M,K), то схему получения хеш-кода h по описанному выше алгоритму можно представить как

В качестве начального хеш-кода h0 берут некоторую константу. Шифрование производится в режиме простой замены. При использовании указанного способа размер блока совпадает с длиной ключа и размером хеш-значения будет длина блока.

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

На самом деле возможны еще несколько схем использования блочного шифра для формирования хеш-функции. Пусть Мi – блок исходного сообщения, hi – значение хеш-функции на i-том этапе, f – блочный алгоритм шифрования, используемый в режиме простой замены, – операция сложения по модулю 2. Тогда возможны, например, следующие схемы формирования хеш-функции:

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

Основным недостатком хеш-функций, спроектированных на основе блочных алгоритмов, является относительно низкая скорость работы. Необходимую криптостойкость можно обеспечить и за меньшее количество операций над входными данными. Существуют более быстрые алгоритмы хеширования, спроектированных самостоятельно, с нуля, исходя из требований криптостойкости (наиболее распространенные из них – MD5, SHA-1, SHA-2 и ГОСТ Р 34.11-94).

функция — это… Что такое Хэш-функция?

Хеширование (иногда хэширование, англ. hashing) — преобразование входного массива данных произвольной длины в выходную битовую строку фиксированной длины. Такие преобразования также называются хеш-функциями или функциями свёртки, а их результаты называют хешем, хеш-кодом или дайджестом сообщения (англ. message digest).

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

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

Контрольные суммы

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

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

Платой за столь высокую скорость является отсутствие криптостойкости — легкая возможность подогнать сообщение под заранее известную сумму. Также обычно разрядность контрольных сумм (типичное число: 32 бита) ниже, чем криптографических хешей (типичные числа: 128, 160 и 256 бит), что означает возможность возникновения непреднамеренных коллизий.

Простейшим случаем такого алгоритма является деление сообщения на 32- или 16- битные слова и их суммирование, что применяется, например, в TCP/IP.

Как правило, к такому алгоритму предъявляются требования отслеживания типичных аппаратных ошибок, таких, как несколько подряд идущих ошибочных бит до заданной длины. Семейство алгоритмов т. н. «циклический избыточных кодов» удовлетворяет этим требованиям. К ним относится, например, CRC32, применяемый в аппаратуре ZIP.

Криптографические хеш-функции

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

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

Согласно парадоксу о днях рождения, нахождение коллизии для хеш-функции с длиной значений n бит требует в среднем перебора около 2n / 2 операций. Поэтому n-битная хеш-функция считается криптостойкой, если вычислительная сложность нахождения коллизий для нее близка к 2n / 2.

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

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

Применение хеширования

Хеш-функции также используются в некоторых структурах данных — хеш-таблицаx и декартовых деревьях. Требования к хеш-функции в этом случае другие:

  • хорошая перемешиваемость данных
  • быстрый алгоритм вычисления

Сверка данных

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

Проверка на наличие ошибок

Например, контрольная сумма может быть передана по каналу связи вместе с основным текстом. На приёмном конце, контрольная сумма может быть рассчитана заново и её можно сравнить с переданным значением. Если будет обнаружено расхождение, то это значит, что при передаче возникли искажения и можно запросить повтор.

Бытовым аналогом хеширования в данном случае может служить приём, когда при переездах в памяти держат количество мест багажа. Тогда для проверки не нужно вспоминать про каждый чемодан, а достаточно их посчитать. Совпадение будет означать, что ни один чемодан не потерян. То есть, количество мест багажа является его хеш-кодом.

Проверка парольной фразы

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

Примером в данном случае могут служить ОС GNU/Linux и Microsoft Windows XP. В них хранятся лишь хеш-значения парольных фраз из учётных записей пользователей.

Ускорение поиска данных

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

Бытовым аналогом хеширования в данном случае может служить помещение слов в словаре по алфавиту. Первая буква слова является его хеш-кодом, и при поиске мы просматриваем не весь словарь, а только нужную букву.

Список алгоритмов

Ссылки

Wikimedia Foundation. 2010.

функция — это… Что такое Хеш-функция?

Хеширование (иногда хэширование, англ. hashing) — преобразование входного массива данных произвольной длины в выходную битовую строку фиксированной длины. Такие преобразования также называются хеш-функциями или функциями свёртки, а их результаты называют хешем, хеш-кодом или дайджестом сообщения (англ. message digest).

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

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

Контрольные суммы

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

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

Платой за столь высокую скорость является отсутствие криптостойкости — легкая возможность подогнать сообщение под заранее известную сумму. Также обычно разрядность контрольных сумм (типичное число: 32 бита) ниже, чем криптографических хешей (типичные числа: 128, 160 и 256 бит), что означает возможность возникновения непреднамеренных коллизий.

Простейшим случаем такого алгоритма является деление сообщения на 32- или 16- битные слова и их суммирование, что применяется, например, в TCP/IP.

Как правило, к такому алгоритму предъявляются требования отслеживания типичных аппаратных ошибок, таких, как несколько подряд идущих ошибочных бит до заданной длины. Семейство алгоритмов т. н. «циклический избыточных кодов» удовлетворяет этим требованиям. К ним относится, например, CRC32, применяемый в аппаратуре ZIP.

Криптографические хеш-функции

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

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

Согласно парадоксу о днях рождения, нахождение коллизии для хеш-функции с длиной значений n бит требует в среднем перебора около 2n / 2 операций. Поэтому n-битная хеш-функция считается криптостойкой, если вычислительная сложность нахождения коллизий для нее близка к 2n / 2.

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

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

Применение хеширования

Хеш-функции также используются в некоторых структурах данных — хеш-таблицаx и декартовых деревьях. Требования к хеш-функции в этом случае другие:

  • хорошая перемешиваемость данных
  • быстрый алгоритм вычисления

Сверка данных

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

Проверка на наличие ошибок

Например, контрольная сумма может быть передана по каналу связи вместе с основным текстом. На приёмном конце, контрольная сумма может быть рассчитана заново и её можно сравнить с переданным значением. Если будет обнаружено расхождение, то это значит, что при передаче возникли искажения и можно запросить повтор.

Бытовым аналогом хеширования в данном случае может служить приём, когда при переездах в памяти держат количество мест багажа. Тогда для проверки не нужно вспоминать про каждый чемодан, а достаточно их посчитать. Совпадение будет означать, что ни один чемодан не потерян. То есть, количество мест багажа является его хеш-кодом.

Проверка парольной фразы

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

Примером в данном случае могут служить ОС GNU/Linux и Microsoft Windows XP. В них хранятся лишь хеш-значения парольных фраз из учётных записей пользователей.

Ускорение поиска данных

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

Бытовым аналогом хеширования в данном случае может служить помещение слов в словаре по алфавиту. Первая буква слова является его хеш-кодом, и при поиске мы просматриваем не весь словарь, а только нужную букву.

Список алгоритмов

Ссылки

Wikimedia Foundation. 2010.

Совсем просто про минимальное идеальное хеширование, основанное на графах / Хабр

Представим, что перед нами стоит классическая задача получить данные по какому-то ключу. Причем количество данных и их ключей заранее известно.

Как решать подобную задачу?

Если количество пар ключ-значение заведомо невелико, то бывает смысл просто захардкодить. Но если таких значений много миллионов?

Можно просто перебором пройтись по списку пока не встретится нужное значение ключа. Но тогда сложность будет линейная O(N), что, в данном случае, должно расстроить любого инженера. А какая сложность алгоритма тогда требуется? Которая не зависит от количества данных и выполняется за фиксированное время, т. е. с константной сложностью O(1).

Как можно получать данные за фиксированное время?

Хеширование

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

Другими словами, нам надо найти способ преобразовывать ключ в смещение, где будут находиться данные. Смещение — это просто целое число: [0, n — 1], где n — количество сохраняемых значений.

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

Но, к сожалению, хеш-функции порождают коллизии, то есть два разных ключа могут давать одинаковое смещение.

Исходя из задачи, у нас фиксированное и заранее известное количество данных, что дает возможность избежать подобных проблем.

Идеальное хеширование

Идеальная хеш-функция (Perfect Hash Function) — это такая хеш-функция, которая преобразует заранее известное статическое множество ключей в диапазон целых чисел [0, m — 1] без коллизий, т. е. один ключ соответствует только одному уникальному значению. А если количество результирующих значений такое же как и количество входящих ключей, такая функция называется Минимальной Идеальной Хеш-функцией (Minimal Perfect Hash Function).
Рассмотрим пример минимальной идеальной хеш-функции основанной на случайных графах.

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


Рис 1. Граф, где ребро соответсвует ключу и описывается через две вершины.

Так как ключ представлен в виде ребра, а ребро всегда соединяет как минимум(потому что бывают еще гиперграфы) две вершины, значит искомая функция может выглядеть примерно так:

h(key) = g(node1, node2)

где h(key) — это минимальная идеальная хеш-функция, значение которой описывает ребро, key — ключ, g() — некая пока неизвестная функция зависящая от вершин графа node1 и node2. Так как они должны зависеть от ключа, то получается

h(key) = g(f1(key), f2(key))

По сути для f1 и f2 можно выбрать любые хеш-функции, которые будут применяться для одного ключа.

Осталось определить неизвестную функцию g(), которая описывает взаимосвязь двух узлов f1(key), f2(key) и ребро.

Вот здесь начинаются фокусы

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

h(key) = (g1(f1(key)) + g2(f2(key))) mod m

где h(key) — это значение ребра, f1(key) — это первый узел графа, g1() — значение этого узла, f2(key) — второй узел, g2() — значение второго узла, m — количество ребер.

Если еще проще, то

значение минимальной идеальной функции = (значение узла 1 + значения узла 2) mod количество ребер.


Рис 2. Представление одного ключа в графе.

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


Рис 3. Коллизии в хеш-функциях порождают несколько ребер на одной вершине. Так же вершины одного ключа могут не соеденяться с вершинами другого ключа.

Вот где соль

Определившись как взаимосвязаны узлы графа с их ребрами, мы сперва определяем значения ребер h(key) (это просто инкрементный индекс), которые будут заведомо уникальны, а потом подбираем значения узлов.

Например, значение последующего узла можно посчитать так:

g2(f2(key)) = h(key) — g1(f1(key))

или

значение узла 2 = значение ребра — значения узла 1

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

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

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

На простом примере

Теперь пришел черед описать сам алгоритм на примере.

Задача: Имеется множество ключей состоящих из названий 12 месяцев. Необходимо создать минимальную идеальную хеш-функцию, где каждый месяц транслируется в только одно уникальное целое число в диапазоне [0, 11].

1. Проходим по всем ключам и добавляем вершины и ребра. Для этого выбираем две хеш-функии f1 и f2.

Например:
Для ключа jan получаем номер первого узла f1(jan) := 4 и номер второго узла f2(jan) := 13
Для ключа feb, f1(feb) := 0, f2(feb) := 17
и так далее.

2. Проверяем получился ли граф зацикленным, если да, то повторяем шаг №1 заново и при этом меняем хеш функции f1/f2.
Вероятность появления цикла в графе зависит от количества возможных вершин. Поэтому введем понятие как фактор размера графа. Количество узлов определяется как:

m = c * n

где m — количество узлов в графе, с — константный фактор размера, n — количество ключей.

3. В случае успешного создания незацикленного графа, надо пройтись по всем узлам и посчитать их значение по формуле

g2(f2(key)) = h(key) — g1(f1(key))

или

значение дочернего узла = индекс ребра — значение узла предка

Например, присваиваем узлу с номером 0 значение 0 и идем по его ребру с индексом 6:

g2(13) = 6 — 0 = 6, узел с номером 13 получает значение 6 и т. д.

В результате имеем такой граф.


Рис 4. Результирующий граф, где ключами выступают имена месяцев и использованы случайные хеш-функции для получения номеров вершин. Числа возле узлов есть значение узла.

Лукап

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

f1(sep) := 17
f2(sep) := 9

Получив номера вершин, складываем их значения:

h(sep) = (g(17) + g(9)) mod 12 = (1 + 7) mod 12 = 8

Данный алгоритм называется CHM и реализован в библиотеке CMPH.
И как можно убедиться, создание хеш-таблицы имеет линейную сложность O(N), а поиск индекса по ключу — константную O(1).

Послесловие

А вы помните бородатую задачку от гугл?
Как скопировать однонаправленный список за линейное время, если узел списка выглядит так?
struct list_node
{
    list_node* next;
    list_node* random;
};

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

А теперь представьте в вашем расположении минимальная идеальная хеш-функция, которая может сохранить по указателю его индекс в списке и по индексу сохранять указатель. И решить задачу можно будет так:

1. Проходим список, получаем массив указателей нод и их индекс.
2. Создаем минимальные идеальные хеш-функции для указателей нод.
3. Создаем новый список, получаем массив индексов нод и их указателей.
4. Создаем другие идеальные функции для индексов второго списка, что бы по индексу получить адрес.
5. Проходим новый список, и получаем адрес старой ноды, по нему получаем индекс, а по второй хеш-функции получаем адрес уже во втором списке по индексу.

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

Спасибо за усилия.

Почитать

1. Z.J. Czech, G. Havas, and B.S. Majewski. An optimal algorithm for generating minimal perfect hash functions., Information Processing Letters, 43(5):257-264, 1992.
2. Minimal Perfect Hash Functions — Introduction.
3. mphf — Моя реализация CHM на C++.

Хеширование — это… Что такое Хеширование?

Хеш-функция, отображающая множество имён в множество натуральныых чисел

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

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

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

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

История

Дональд Кнут относит первую систематическую идею хеширования к сотруднику IBM Хансу Петеру Луну (нем. Hans Peter Luhn), предложившему хеш-кодирование в январе 1953 года.

В 1956 году Арнольд Думи (англ. Arnold Dumey) в своей работе «Computers and automation» первым представил концепцию хеширования таковой, какой её знает большинство программистов сейчас. Думи рассматривал хеширование, как решение «Проблемы словаря», а также предложил использовать в качестве хеш-адреса остаток деления на простое число.[1]

Первой серьёзной работой, связанной с поиском в больших файлах, была статья Уэсли Питерсона (англ. W. Wesley Peterson) в IBM Journal of Research and Development 1957 года, в которой он определил открытую адресацию, а также указал на ухудшение производительности при удалении. Спустя шесть лет был опубликована работа Вернера Бухгольца (нем. Werner Buchholz), в которой проведено обширное исследование хеш-функций. В течение нескольких последующих лет хеширование широко использовалось, однако не было опубликовано никаких значимых работ.

В 1967 году хеширование в современном значении упомянуто в книге Херберта Хеллермана «Принципы цифровых вычислительных систем»[2]. В 1968 году Роберт Моррис (англ. Robert Morris) опубликовал в Communications of the ACM большой обзор по хешированию, эта работа считается ключевой публикацией, вводящей понятие о хешировании в научный оборот и закрепившей ранее применявшийся только в жаргоне специалистов термин «хеш».

До начала 1990-х годов в русскоязычной литературе в качестве эквивалента термину «хеширование» благодаря работам Андрея Ершова использовалось слово «расстановка», а для коллизий использовался термин «конфликт» (Ершов использовал «расстановку» с 1956 года, в русскоязычном издании книги Вирта «Алгоритмы и структуры данных» 1989 года также используется термин «расстановка»). Предлагалось также назвать метод русским словом «окрошка». Однако ни один из этих вариантов не прижился, и в русскоязычной литературе используется преимущественно термин «хеширование».[3]

Виды хеш-функций

Хорошая хеш-функция должна удовлетворять двум свойствам:

  1. Быстро вычисляться;
  2. Минимизировать количество коллизий

Предположим, для определённости, что количество ключей , а хеш-функция имеет не более различных значений:

В качестве примера «плохой» хеш-функции можно привести функцию с , которая десятизначному натуральном числу сопоставляет три цифры выбранные из середины двадцатизначного квадрата числа . Казалось бы значения хеш-кодов должны равномерно распределиться между «000» и «999», но для реальных данных такой метод подходит лишь в том случае, если ключи не имеют большого количества нулей слева или справа.[3]

Однако существует несколько более простых и надежных методов, на которых базируются многие хеш-функции.

Хеш-функции основанные на делении

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

При этом очевидно, что при чётном значение функции будет чётным, при чётном , и нечётным — при нечётном, что может привести к значительному смещению данных в файлах. Также не следует использовать в качестве степень основания счисления компьютера, так как хеш-код будет зависеть только от нескольких цифр числа , расположенных справа, что приведет к большому количеству коллизий. На практике обычно выбирают простое  — в большинстве случаев этот выбор вполне удовлетворителен.

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

При правильном выборе такой способ гарантирует отсутствие коллизий между почти одинаковыми ключами.[3]

Мультипликативная схема хеширования

Второй метод состоит в выборе некоторой целой константы , взаимно простой с , где  — количество представимых машинным словом значений (в компьютерах IBM PC ). Тогда можем взять хеш-функцию вида:

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

Среди преимуществ этих двух методов стоит отметь, что они выгодно используют то, что реальные ключи неслучайны, например в том случае если ключи представляют собой арифметическую прогрессию (допустим последовательность имён «ИМЯ1», «ИМЯ2», «ИМЯ3»). Мультипликативный метод отобразит арифметическую прогрессию в приближенно арифметическую прогрессию различных хеш-значений, что уменьшает количество коллизий по сравнению со случайной ситуацией.[3]

Одной из вариаций данного метода является хеширование Фибоначчи, основанное на свойствах золотого сечения. В качестве здесь выбирается ближайшее к целое число, взаимно простое с [3]

Хеширование строк переменной длины

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

Хеширование Пирсона (англ. Pearson hashing) — алгоритм, предложенный Питером Пирсоном (англ. Peter Pearson) для процессоров с 8-битными регистрами, задачей которого является быстрое вычисление хеш-кода для строки произвольной длины. На вход функция получается слово , состоящее из символов, каждый размером 1 байт, и возвращает значение в диапазоне от 0 до 255. Причем значение хеш-кода зависит от каждого символа входного слова.

Алгоритм можно описать следующим псевдокодом, который получает на вход строку и использует таблицу перестановок

h := 0
for each c in W loop
  index := h xor c
  h := T[index]
end loop
return h

Среди преимуществ алгоритма следует отметить:

  • Простоту вычисления;
  • Не существует таких входных данных, для которых вероятность коллизии наибольшая;
  • Возможность модификации в идеальную хеш-функцию.[4]

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

[3]

Идеальное хеширование

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

Описание
  1. Функция называется идеальной хеш-функцией для , если она инъективна на ;
  2. Функция называется минимальной идеальной хеш-функцией для , если она является ИХФ и ;
  3. Для целого , функция называется -идеальной хеш-функцией (k-PHF) для если для каждого имеем .

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

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

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

Описание

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

В качестве решения такой проблемы можно выбирать функцию случайным образом из определенного набора, называемого универсальным семейством .[6]

Методы борьбы с коллизиями

Как уже говорилось выше, коллизией (иногда конфликтом[1] или столкновением) хеш-функции называются такие два входных блока данных, которые дают одинаковые хеш-коды.

В хеш-таблицах

Большинство первых работ описывающих хеширование было посвящено методам борьбы с коллизиями в хеш-таблицах, так как хеш-функции применялись для поиска в больших файлах. Существует два основных метода используемых в хеш-таблицах:

  1. Метод цепочек(метод прямого связывания)
  2. Метод открытой адресации

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

Второй метод состоит в том, что в массиве таблицы хранятся пары ключ-значение. Таким образом мы полностью отказываемся от ссылок и просто просматриваем записи таблицы, пока не найдем нужный ключ или пустую позицию. Последовательность, в которой просматриваются ячейки таблицы называется последовательностью проб.[3]

Криптографическая соль

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

Применение хеш-функций

Хеш-функции широко используются в криптографии, а также во многих структурах данных — хеш-таблицаx, фильтрах Блума и декартовых деревьях.

Криптографические хеш-функции

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

  • Необратимость: для заданного значения хеш-функции m должно быть вычислительно неосуществимо найти блок данных , для которого .
  • Стойкость к коллизиям первого рода: для заданного сообщения M должно быть вычислительно неосуществимо подобрать другое сообщение N, для которого .
  • Стойкость к коллизиям второго рода: должно быть вычислительно неосуществимо подобрать пару сообщений , имеющих одинаковый хеш.

Данные требования не являются независимыми:

  • Обратимая функция нестойка к коллизиям первого и второго рода.
  • Функция, нестойкая к коллизиям первого рода, нестойка к коллизиям второго рода; обратное неверно.

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

Атака «дней рождения» позволяет находить коллизии для хеш-функции с длиной значений n битов в среднем за примерно вычислений хеш-функции. Поэтому n-битная хеш-функция считается криптостойкой, если вычислительная сложность нахождения коллизий для неё близка к .

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

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

Контрольные суммы

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

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

Платой за столь высокую скорость является отсутствие криптостойкости — лёгкая возможность подогнать сообщение под заранее известную сумму. Также обычно разрядность контрольных сумм (типичное число: 32 бита) ниже, чем криптографических хешей (типичные числа: 128, 160 и 256 бит), что означает возможность возникновения непреднамеренных коллизий.

Простейшим случаем такого алгоритма является деление сообщения на 32- или 16- битные слова и их суммирование, что применяется, например, в TCP/IP.

Как правило, к такому алгоритму предъявляются требования отслеживания типичных аппаратных ошибок, таких, как несколько подряд идущих ошибочных бит до заданной длины. Семейство алгоритмов т. н. «циклических избыточных кодов» удовлетворяет этим требованиям. К ним относится, например, CRC32, применяемый в устройствах Ethernet и в формате сжатия данных ZIP.

Контрольная сумма, например, может быть передана по каналу связи вместе с основным текстом. На приёмном конце, контрольная сумма может быть рассчитана заново и её можно сравнить с переданным значением. Если будет обнаружено расхождение, то это значит, что при передаче возникли искажения и можно запросить повтор.

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

Геометрическое хеширование

Геометрическое хеширование (англ. Geometric hashing) – широко применяемый в компьтерной графике и вычислительной геометрии метод для решения задач на плоскости или в трёхмерном пространстве, например для нахождения ближайших пар в множестве точек или для поиска одинаковых изображений. Хеш-функция в данном методе обычно получает на вход какое-либо метрическое пространство и разделяет его, создавая сетку из клеток. Таблица в данном случае является массивом с двумя или более индексами и называется файл сетки(англ. Grid file). Геометрическое хеширование также применяется в телекоммуникациях при работе с многомерными сигналами.[8]

Ускорение поиска данных

Хеш-таблицей называется структура данных, позволяющая хранить пары вида (ключ,хеш-код) и поддерживающая операции поиска, вставки и удаления элемента. Задачей хеш-таблиц является ускорение поиска, например, при записи текстовых полей в базе данных может рассчитываться их хеш код и данные могут помещаться в раздел, соответствующий этому хеш-коду. Тогда при поиске данных надо будет сначала вычислить хеш-код текста и сразу станет известно, в каком разделе их надо искать, то есть, искать надо будет не по всей базе, а только по одному её разделу (это сильно ускоряет поиск).

Бытовым аналогом хеширования в данном случае может служить помещение слов в словаре по алфавиту. Первая буква слова является его хеш-кодом, и при поиске мы просматриваем не весь словарь, а только нужную букву.

Примечания

  1. 1 2 Никлаус Вирт.Алгоритмы и структуры данных
  2. Herbert Hellerman. Digital Computer System Principles. N.Y.: McGraw-Hill, 1967, 424 pp.
  3. 1 2 3 4 5 6 7 Дональд Кнут. Искусство программирования
  4. Pearson, Peter K. (June 1990), ««Fast Hashing of Variable-Length Text Strings»», Communications of the ACM Т. 33 (6): 677, doi:10.1145/78973.78978, <http://portal.acm.org/citation.cfm?id=78978> 
  5. Djamal Belazzougui, Fabiano C. Botelho, Martin Dietzfelbinger (2009). «Hash, displace, and compress» (PDF) (Springer Berlin / Heidelberg). Проверено 2011-08-11.
  6. Miltersen, Peter Bro Universal Hashing (PDF). Архивировано из первоисточника 24 июня 2009.
  7. Брюс Шнаейр, Прикладная криптография. Протоколы, алгоритмы, исходные тексты на языке Си
  8. Wolfson, H.J. & Rigoutsos, I (1997). Geometric Hashing: An Overview. IEEE Computational Science and Engineering, 4(4), 10-21.

Литература

  • Брюс Шнайер «Прикладная криптография. Протоколы, алгоритмы, исходные тексты на языке Си». — М.: Триумф, 2002. — ISBN 5-89392-055-4
  • Дональд Кнут Искусство программирования, том 3. Сортировка и поиск = The Art of Computer Programming, vol.3. Sorting and Searching. — 2-е изд. — М.: «Вильямс», 2007. — С. 824. — ISBN 0-201-89685-0
  • Никлаус Вирт «Алгоритмы и структуры данных». — М.: Мир, 1989. — ISBN 5-03-001045-9

Ссылки

Универсальное и идеальное хеширование / Блог компании OTUS. Онлайн-образование / Хабр

Начинаем неделю с полезного материала приуроченного к запуску курса «Алгоритмы для разработчиков». Приятного прочтения.

1. Обзор

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

Материал, освещенный в этой лекции, включает в себя:

  • Формальная постановка и общая идея хеширования.
  • Универсальное хеширование.
  • Идеальное хеширование.

2. Вступление

Мы рассмотрим основную проблему со словарем, которую мы обсуждали до этого, и рассмотрим две версии: статическую и динамическую:

  • Статическая: дано множество элементов S, мы хотим хранить его таким образом, чтобы можно было быстро выполнять поиск.
  • Например, фиксированный словарь.
  • Динамическая: здесь у нас есть последовательность запросов на вставку, поиск и, возможно, удаление. Мы хотим сделать все это эффективно.

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

3. Основы хеширования

Формальная постановка для хеширования заключается в следующем.

  • Ключи принадлежат некоторому большому множеству U. (Например, представьте, что U — набор всех строк длиной не более 80 символов ascii.)
  • Есть некоторое множество ключей S в U, которое нам на самом деле нужно (ключи могут быть как статическими, так и динамическими). Пусть N = |S|. Представьте, что N гораздо меньше, чем размер U. Например, S — это множество имен учеников в классе, которое намного меньше, чем 128^80.
  • Мы будем выполнять вставки и поиск с помощью массива A некоторого размера M и хеш-функции h: U → {0,…, М — 1}. Дан элемент x, идея хеширования состоит в том, что мы хотим хранить его в A[h(x)]. Обратите внимание, что если бы U было маленьким (например, 2-символьные строки), то можно было бы просто сохранить x в A[x], как в блочной сортировке. Проблема в том, что U большое, поэтому нам нужна хеш-функция.
  • Нам нужен метод для разрешения коллизий. Коллизия — это когда h(x) = h(y) для двух разных ключей x и y. В этой лекции мы будем обрабатывать коллизии, определяя каждый элемент A как связанный список. Есть ряд других методов, но для проблем, на которых мы сосредоточимся здесь, это самый подходящий. Этот метод называется методом цепочек. Чтобы вставить элемент, мы просто помещаем его в начало списка. Если h — хорошая хеш-функция, то мы надеемся, что списки будут небольшими.

Одним из замечательных свойств хеширования является то, что все словарные операции невероятно просты в реализации. Чтобы выполнить поиск ключа x, просто вычислите индекс i = h(x) и затем идите по списку в A[i], пока не найдете его (или не выйдете из списка). Чтобы вставить, просто поместите новый элемент в верхней части его списка. Чтобы удалить, нужно просто выполнить операцию удаления в связанном списке. Теперь мы переходим к вопросу: что нам нужно для достижения хорошей производительности?

Желательные свойства. Основные желательные свойства для хорошей схемы хеширования:

  1. Ключи хорошо рассредоточены, чтобы у нас не было слишком много коллизий, так как коллизии влияют на время выполнения поиска и удаления.
  2. M = O(N): в частности, мы бы хотели, чтобы наша схема достигла свойства (1) без необходимости, чтобы размер таблицы M был намного больше, чем число элементов N.
  3. Функция h должна быстро вычисляться. В нашем сегодняшнем анализе мы будем рассматривать время для вычисления h(x) как константу. Тем не менее, стоит помнить, что она не должна быть слишком сложной, потому что это влияет на общее время выполнения.

Учитывая это, время поиска элемента x равно O(размер списка A[h(x)]). То же самое верно для удалений. Вставки занимают время O(1) независимо от длины списков. Итак, мы хотим проанализировать, насколько большими получаются эти списки.

Базовая интуиция: один из способов красиво распределить элементы — это распределить их случайным образом. К сожалению, мы не можем просто использовать генератор случайных чисел, чтобы решить, куда направить следующий элемент, потому что тогда мы никогда не сможем найти его снова. Итак, мы хотим, чтобы h было чем-то «псевдослучайным» в некотором формальном смысле.

Сейчас мы изложим некоторые плохие новости, а затем некоторые хорошие.

Утверждение 1 (Плохие новости) Для любой хэш-функции h, если |U| ≥ (N −1) M +1, существует множество S из N элементов, которые все хешируются в одном месте.

Доказательство: по принципу Дирихле. В частности, чтобы рассмотреть контрапозиции, если бы каждое местоположение имело не более N — 1 элементов U, хэширующих его, то U мог бы иметь размер не более M (N — 1).

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

Вот ключевая идея: давайте использовать рандомизацию в нашей конструкции h, по аналогии с рандомизированной быстрой сортировкой. (Само собой разумеется, h будет детерминированной функцией). Мы покажем, что для любой последовательности операций вставки и поиска (нам не нужно предполагать, что набор вставленных элементов S является случайным), если мы выберем h таким вероятностным способом, производительность h в этой последовательности будет хорошо в ожидании. Таким образом, это та же самая гарантия, что и в рандомизированной быстрой сортировке или ловушках. В частности, это идея универсального хеширования.

Как только мы разработаем эту идею, мы будем использовать ее для особенно приятного приложения под названием «идеальное хеширование».

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

Определение 1. Рандомизированный алгоритм H для построения хеш-функций h: U → {1, …, М}
универсален, если для всех x != y в U имеем

Мы также можем сказать, что множество H хеш-функций является универсальным семейством хеш-функций, если процедура «выбрать h ∈ H наугад» универсальна. (Здесь мы отождествляем множество функций с равномерным распределением по множеству.)

Теорема 2. Если H универсален, то для любого множества S ⊆ U размера N, для любого x ∈ U (например, который мы могли бы искать), если мы строим h случайным образом в соответствии с H, ожидаемое число коллизий между х и другими элементами в S не более N/M.

Доказательство: у каждого y ∈ S (y != x) есть не более 1 / M шанса столкновения с x по определению «универсального». Так,

  • Пусть Cxy = 1, если x и y сталкиваются, и 0 в противном случае.
  • Пусть Cx обозначает общее количество столкновений для x. Итак, Cx = Py∈S, y != x Cxy.
  • Мы знаем, что E [Cxy] = Pr (x и y сталкиваются) ≤ 1 / M.
  • Таким образом, по линейности ожидания E [Cx] = Py E [Cxy] <N / M.

Теперь мы получаем следующее следствие.

Следствие 3. Если H универсален, то для любой последовательности операций L вставки, поиска и удаления, в которых в системе одновременно может быть не более M элементов, ожидаемая общая стоимость L операций для случайного h ∈ H равна только O (L) (просмотр времени для вычисления h как константы).

Доказательство: для любой данной операции в последовательности ее ожидаемая стоимость постоянна по теореме 2, поэтому ожидаемая общая стоимость L операций равна O (L) по линейности ожидания.

Вопрос: можем ли мы на самом деле построить универсальную H? Если нет, то это все довольно бессмысленно. К счастью, ответ — да.

4.1. Создание универсального хеш-семейства: матричный метод

Допустим, ключи имеют длину u-бит. Скажем, размер таблицы M равен степени 2, поэтому индекс длиной b-битов с M = 2b.

Что мы сделаем, это выберем h в качестве случайной матрицы 0/1 b-by-u и определим h (x) = hx, где мы добавим mod 2. Эти матрицы короткие и толстые. Например:

Утверждение 4. Для x != y Prh [h (x) = h (y)] = 1 / M = 1 / 2b.

Доказательство: во-первых, что означает умножение h на x? Мы можем думать об этом как о добавлении некоторых из столбцов h (делая векторное сложение mod 2), где 1 бит в x указывает, какие из них добавить. (например, мы добавили 1-й и 3-й столбцы h выше)

Теперь возьмем произвольную пару ключей x, y такую, что x != y. Они должны где-то отличаться, так что, скажем, они различаются по i-й координате, а для конкретности скажем xi = 0 и yi = 1. Представьте, что сначала мы выбрали все h, кроме i-го столбца. По оставшимся выборкам i-го столбца h (x) является фиксированным. Однако каждая из 2b различных настроек i-го столбца дает различное значение h (y) (в частности, каждый раз, когда мы переворачиваем бит в этом столбце, мы переворачиваем соответствующий бит в h (y)). Таким образом, есть точно 1 / 2b шанс, что h (x) = h (y).

Существуют и другие методы построения универсальных хеш-семейств, основанных также на умножении простых чисел (см. Раздел 6.1).

Следующий вопрос, который мы рассмотрим: если мы исправим множество S, сможем ли мы найти хеш-функцию h такую, что все поиски будут иметь постоянное время? Ответ — да, и это приводит к теме идеального хеширования.

5. Идеальное хеширование

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

5.1 Метод 1: решение в пространстве O(N2)

Скажем, мы хотим иметь таблицу, размер которой квадратичен по размеру N нашего словаря S. Тогда вот простой метод построения идеальной хеш-функции. Пусть H универсален и M = N2. Тогда просто выберите случайный h из H и попробуйте! Утверждение состоит в том, что есть по крайней мере 50% шанс, что у нее не будет коллизий.

Утверждение 5. Если H универсален и M = N2, то Prh∼H (нет коллизий в S) ≥ 1/2.

Доказательство:

• Сколько пар (x, y) есть в S? Ответ:
• Для каждой пары вероятность их столкновения составляет ≤ 1 / M по определению универсальности.
• Итак, Pr (существует коллизия) ≤ / M <1/2.

Это как другая сторона «парадокса дня рождения». Если количество дней намного больше, чем количество людей в квадрате, то есть разумный шанс, что ни у одной пары не будет одинакового дня рождения.

Итак, мы просто выбираем случайную h из H, и если возникают какие-либо коллизии, мы просто выбираем новую h. В среднем нам нужно будет сделать это только дважды. Теперь, что если мы хотим использовать только пространство O(N)?

5.2 Метод 2: решение в пространстве O(N)

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

Способ заключается в следующем. Сначала мы будем хэшировать в таблицу размера N, используя универсальное хеширование. Это приведет к некоторым коллизиям (если только нам не повезет). Однако затем мы перехешируем каждую корзину, используя метод 1, возводя в квадрат размер корзины, чтобы получить нулевые коллизии. Таким образом, схема состоит в том, что у нас есть хеш-функция первого уровня h и таблица A первого уровня, а затем N хеш-функций второго уровня h2,…, hN и N таблицы второго уровня A1,…, А.Н… Чтобы найти элемент x, мы сначала вычисляем i = h (x), а затем находим элемент в Ai [hi (x)]. (Если бы вы делали это на практике, вы могли бы установить флаг так, чтобы вы делали второй шаг, только если на самом деле были коллизии с индексом i, а в противном случае просто помещали бы сам x в A [i], но давайте не будем об этом беспокоиться здесь .)

Скажем, хеш-функция h хеширует n элементов S в местоположение i. Мы уже доказывали (анализируя метод 1), что мы можем найти h2,…, hN, так что общее пространство, используемое во вторичных таблицах, равно Pi (ni) 2. Осталось показать, что мы можем найти функцию первого уровня h такую, что Pi (ni) 2 = O (N). На самом деле, мы покажем следующее:

Теорема 6. Если мы выберем начальную точку h из универсального множества H, то

Pr[X
i
(ni)2 > 4N] < 1/2.

Доказательство. Докажем это, показав, что E [Pi (ni) 2]

Теперь, хитрый трюк заключается в том, что один из способов подсчитать это количество — подсчитать количество упорядоченных пар, у которых возникает коллизия, включая коллизии с самим собой. Например, если корзина имеет {d, e, f}, то у d возникнет коллизия с каждым из {d, e, f}, у e возникнет коллизия с каждым из {d, e, f}, и у f возникнет коллизия с каждым из {d, e, f}, поэтому мы получаем 9. Итак, мы имеем:

E[X
i
(ni)2] = E[X
x
X
y
Cxy] (Cxy = 1 if x and y collide, else Cxy = 0)
= N +X
x
X
y6=x
E[Cxy]
≤ N + N(N − 1)/M (where the 1/M comes from the definition of universal)
< 2N. (since M = N)

Итак, мы просто пробуем случайное h из H, пока не найдем такое, что Pi n2 i

6. Дальнейшее обсуждение

6.1 Еще один метод универсального хеширования

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

В матричном методе мы рассматривали ключ как вектор битов. В этом методе вместо этого мы будем рассматривать ключ x как вектор целых чисел [x1, x2,…, xk] с единственным требованием, чтобы каждый xi находился в диапазоне {0, 1,…, М-1}. Например, если мы хешируем строки длиной k, то xi может быть i-м символом (если размер нашей таблицы не менее 256) или i-й парой символов (если размер нашей таблицы не менее 65536). Кроме того, мы будем требовать, чтобы размер нашей таблицы M был простым числом. Чтобы выбрать хеш-функцию h, мы выберем k случайных чисел r1, r2,…, рк из {0, 1,…, M — 1} и определить:

h(x) = r1x1 + r2x2 + . . . + rkxk mod M.

Доказательство того, что этот метод универсален, строится точно так же, как доказательство матричного метода. Пусть x и y два разных ключа. Мы хотим показать, что Prh (h (x) = h (y)) ≤ 1 / M. Поскольку x != y, должен быть случай, когда существует некоторый индекс i такой, что xi != yi. Теперь представьте, что сначала вы выбрали все случайные числа rj для j != i. Пусть h ′ (x) = Pj6 = i rjxj. Итак, выбрав ri, мы получим h (x) = h ′ (x) + rixi. Это означает, что у нас возникает коллизия между x и y именно тогда, когда
h′(x) + rixi = h′(y) + riyi mod M, or equivalently when
ri(xi − yi) = h′(y) − h′(x) mod M.

Поскольку M — простое, деление на ненулевое значение mod M является допустимым (каждое целое число от 1 до M −1 имеет мультипликативный обратный по модулю M), что означает, что существует ровно одно значение ri по модулю M, для которого выполняется приведенное выше уравнение истина, а именно ri = (h ′ (y) — h ′ (x)) / (xi — yi) mod M. Таким образом, вероятность этого происшествия равна точно 1 / M.

6.2 Другое использование хеширования

Предположим, у нас есть длинная последовательность элементов, и мы хотим увидеть, сколько разных элементов находятся в списке. Есть ли хороший способ сделать это?

Одним из способов является создать хеш-таблицу, а затем сделать один проход по последовательности, сделав для каждого элемента поиск и затем вставку, если его еще нет в таблице. Количество отдельных элементов — это просто количество вставок.

А теперь, что если список действительно огромен и у нас нет места для его хранения, но нам подойдёт приблизительный ответ. Например, представьте, что мы являемся маршрутизатором и наблюдаем, как проходит много пакетов, и мы хотим (приблизительно) увидеть, сколько существует различных IP-адресов источника.

Вот хорошая идея: скажем, у нас есть хеш-функция h, которая ведет себя как случайная функция, и давайте представим, что h (x) — действительное число от 0 до 1. Одна вещь, которую мы можем сделать, это просто отслеживать минимальный хеш стоимость произведена до сих пор (поэтому у нас не будет таблицы вообще). Например, если ключи 3,10,3,3,12,10,12 и h (3) = 0,4, h (10) = 0,2, h (12) = 0,7, то мы получим 0,2.

Дело в том, что если мы выберем N случайных чисел в [0, 1], ожидаемое значение минимума будет 1 / (N + 1). Кроме того, есть хороший шанс, что он довольно близок (мы можем улучшить нашу оценку, запустив несколько хеш-функций и взяв медиану минимумов).

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

Друзья, была ли эта статья полезной для вас? Пишите в комментарии и присоединяйтесь ко дню открытых дверей, который пройдет уже 25 апреля.

Что такое хеш-функция

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

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

Что такое хеш-функция?

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

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

Уникальные значения хеширования: разные входные данные никогда не генерируют одинаковый результат

С помощью хеш-функции невозможно сгенерировать одинаковые хешированные выходные данные из другого входного текста. Например, давая вход X, хэш-функция генерирует выход Y, но невозможно сгенерировать выход Y с любым другим входным текстом, кроме X.

Быстрее

Хеш-функция работает быстрее, чем обычное симметричное шифрование; независимо от того, какую длину ввода вы даете функции, она всегда будет обеспечивать вывод в разумные сроки.

Вывод фиксированной длины

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

Небольшое изменение ввода даст другой вывод

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

Только в одну сторону (сопротивление предварительного изображения)

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

Он отличается от шифрования, поскольку шифрование — это двусторонняя операция; вы всегда можете расшифровать зашифрованное значение с помощью правильного секрета.

Например, здесь у нас есть входное значение «abc», а хеш-функция сгенерировала хешированное значение «ba7816bf8f01cfea414140de5dae 2223b0031a396177a9cb410ff61f20015ad», теперь из этого хешированного значения трудно получить фактический вход.

Как хеш-функция используется в цепочке блоков

Хеши используются для представления текущего состояния цепочки блоков и обеспечивают неизменность цепочки блоков. Каждая транзакция содержит некоторую информацию, такую ​​как адрес отправителя, адрес получателя, временную метку суммы и так далее; эта информация объединяется и передается в хэш-функцию, которая генерирует уникальное значение хеш-функции, называемое хеш-кодом транзакции или идентификатором транзакции. Этот хеш используется для проверки и может быть подтвержден, что конкретная транзакция произошла в цепочке блоков или нет.

Первый блок в цепочке блоков известен как генезисный блок; который содержит информацию о транзакциях; объединить все транзакции создает новый хеш. Когда создается второй блок, хэш исходного блока добавляется ко всем транзакциям в новом блоке — эта комбинация используется для генерации нового соответствующего хэша.

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

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

.

Криптографическая хеш-функция — Простая английская Википедия, бесплатная энциклопедия

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

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

Идеальная хеш-функция имеет три основных свойства:

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

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

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

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

  1. Нахождение (ранее невидимого) сообщения, которое соответствует заданным значениям хеш-функции.
  2. Обнаружение «коллизий», при которых два разных сообщения имеют одинаковое значение хеш-функции.

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

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

В различных стандартах и ​​приложениях две наиболее часто используемые хэш-функции — это MD5 и SHA-1.

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

В 2007 году Национальный институт стандартов и технологий объявил конкурс на разработку хэш-функции, которая будет называться SHA-3 и станет предметом стандарта FIPS. [1]

.

Что такое хеширование? [Пошаговое руководство — Под капотом блокчейна]

Поделись и получи +16 +16

Итак, что же такое хеширование?

TL; DR:

  1. При хешировании создается значение или значения из строки текста с использованием математической функции.
  2. Хеширование — это один из способов обеспечения безопасности в процессе передачи сообщения, когда сообщение предназначено только для определенного получателя.Формула генерирует хеш, который помогает защитить безопасность передачи от несанкционированного доступа.


Важно знать, как работает хеширование блокчейна. Однако для этого нам нужно сначала понять один из основных принципов, которые лежат в основе создания цепочки блоков. Технология блокчейн — одно из самых инновационных и определяющих эпоху открытий прошлого века. Учитывая то влияние, которое оно оказало за последние несколько лет, и влияние, которое оно окажет в будущем, это, конечно, не будет преувеличением.Чтобы понять, как работают различные криптовалюты, такие как Ethereum и Bitcoin.

Так что же такое хеширование?


Проще говоря, хеширование означает получение входной строки любой длины и выдачу выходных данных фиксированной длины. В контексте криптовалют, таких как биткойн, транзакции принимаются как входные и проходят через алгоритм хеширования (биткойн использует SHA-256), который дает результат фиксированной длины.

Давайте посмотрим, как работает процесс хеширования. Мы собираемся внести определенные вклады.Для этого упражнения мы собираемся использовать SHA-256 (алгоритм безопасного хеширования 256).

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

Криптографические хеш-функции

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

Свойство 1: Детерминированный

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

Свойство 2: Быстрое вычисление

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

Свойство 3: Сопротивление предварительного изображения

Какие состояния сопротивления прообраза заключаются в том, что при H (A) невозможно определить A, где A — вход, а H (A) — выходной хэш.Обратите внимание на использование слова «невозможно» вместо «невозможно». Мы уже знаем, что невозможно определить исходный ввод по его хэш-значению. Возьмем пример.

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

Но это работает только тогда, когда заданный объем данных очень меньше. Что происходит, когда у вас огромный объем данных? Предположим, вы имеете дело со 128-битным хешем. Единственный способ, которым вы должны найти исходный ввод, — это использовать «метод грубой силы». Метод грубой силы в основном означает, что вам нужно выбрать случайный ввод, хэшировать его, а затем сравнить результат с целевым хешем и повторять, пока не найдете совпадение.

Итак, что будет, если воспользоваться этим методом?

  • Лучший сценарий: Вы получите ответ с первой попытки.38. Другими словами, это огромное количество.

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

Свойство 4: Небольшие изменения ввода изменяют хеш.

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

.

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

Свойство 5: Устойчивость к столкновениям

Учитывая два разных входа A и B, где H (A) и H (B) — их соответствующие хэши, невозможно, чтобы H (A) было равно H (B). Это означает, что по большей части каждый вход будет иметь свой уникальный хэш. Почему мы сказали «по большей части»? Давайте поговорим об интересной концепции под названием «Парадокс дня рождения».

Что такое парадокс дня рождения?

Если вы встретите на улице случайного незнакомца, шансы, что у вас обоих одинаковый день рождения, очень низки. Фактически, если предположить, что все дни года имеют одинаковую вероятность иметь день рождения, вероятность того, что другой человек разделит ваш день рождения, составляет 1/365, что составляет 0,27%. Другими словами, он действительно низкий.

Однако, если вы соберете 20-30 человек в одной комнате, вероятность того, что у двух человек будет один и тот же день рождения, астрономически возрастет.Фактически, в этом сценарии есть 50 на 50 шансов, что 2 человека будут праздновать один день рождения!

Изображение предоставлено: (YouTube)

Почему это происходит? Это из-за простого правила вероятности, которое гласит: Предположим, у вас есть N различных возможностей возникновения события, тогда вам нужен квадратный корень из N случайных элементов, чтобы они имели 50% шанс столкновения.

Итак, применяя эту теорию к дням рождения, у вас есть 365 различных вариантов дней рождения, поэтому вам просто понадобится Sqrt (365), что составляет ~ 23 ~, случайно выбранных людей для 50% вероятности того, что двое людей разделяют дни рождения.64-й экземпляр.

Как видите, преодолеть сопротивление столкновению намного проще, чем сопротивление прообразу. Никакая хеш-функция не свободна от коллизий, но обычно на поиск коллизии уходит много времени. Итак, если вы используете такую ​​функцию, как SHA-256, можно с уверенностью предположить, что если H (A) = H (B), то A = B.

Свойство 6: Совместимость с головоломками

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

Для каждого выхода «Y», если k выбирается из распределения с высокой минимальной энтропией, невозможно найти такой вход x, что H (k | x) = Y.

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

Что означает «высокая мин-энтропия»?

Это означает, что распределение, из которого выбирается значение, настолько сильно распределено, что вероятность выбора случайного значения ничтожно мала.По сути, если вам было предложено выбрать число от 1 до 5, это низкое распределение минимальной энтропии. Однако, если вы выберете число от 1 до миллиарда, это будет высокое распределение минимальной энтропии.

Что означает «k | x»?

Знак «|» обозначает конкатенацию. Конкатенация означает сложение двух строк вместе. Например. Если бы я связал «СИНИЙ» и «НЕБО» вместе, то результат был бы «СИНИЙ».

Итак, давайте вернемся к определению.

Предположим, у вас есть выходное значение «Y».Если вы выберете случайное значение «k» из широкого распределения, невозможно найти такое значение X, что хэш конкатенации k и x даст результат Y.

Еще раз обратите внимание на слово «неосуществимо», это не невозможно, потому что люди делают это постоянно. Фактически, весь процесс майнинга работает на этом (подробнее об этом позже).

Примеры криптографических хеш-функций

  • MD 5: Создает 128-битный хэш. Устойчивость к коллизиям была нарушена после ~ 2 ^ 21 хеша.61 хеш.
  • SHA 256: производит 256-битный хэш. В настоящее время это используется биткойнами.
  • Keccak-256: производит 256-битный хэш и в настоящее время используется Ethereum.

Хеширование и структуры данных

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

  1. Указатели.
  2. Связанные списки.

Указатели

Указатели — это программные переменные, в которых хранится адрес другой переменной.Обычно обычные переменные на любом языке программирования хранят данные.

Напр. int a = 10 означает, что существует переменная «a», в которой хранятся целочисленные значения. В этом случае он сохраняет целое число, равное 10. Это обычная переменная.

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

Связанные списки

Связанный список — один из самых важных элементов в структурах данных.Так выглядит связанный список:

.

новейших вопросов о хэш-функциях — Stack overflow на русском

Переполнение стека
  1. Около
  2. Продукты
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
  3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
  4. Талант Нанимайте технических специалистов и создавайте свой бренд работодателя
  5. Реклама Обратитесь к разработчикам и технологам со всего мира
.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *