Функции mhash


Содержание

LXXVI. Mhash Functions

This is an interface to the mhash library. mhash supports a wide variety of hash algorithms such as MD5, SHA1, GOST, and many others. For a complete list of supported hashes, refer to the documentation of mhash. The general rule is that you can access the hash algorithm from PHP with MHASH_HASHNAME. For example, to access TIGER you use the PHP constant MHASH_TIGER.

You need to compile PHP with the —with-mhash[=DIR] parameter to enable this extension. DIR is the mhash install directory.

Данное расширение не определяет никакие директивы конфигурации в php.ini .

Данное расширение не определяет никакие типы ресурсов.

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

Here is a list of hashes which are currently supported by mhash. If a hash is not listed here, but is listed by mhash as supported, you can safely assume that this documentation is outdated.

Хэш-функции: понятие и основы

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

Что это такое?

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

Характеристики

Рассмотрим ключевые характеристики исследуемых алгоритмов. В числе таковых:

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

В числе иных важнейших свойств хэш-функции:

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

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

Требования к хэш-функциям

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

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

Структура

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

В какой структуре может быть представлена используемая в подобных целях хеш-функция? Пример ее составления может быть таким: H (hash, то есть, хэш) = f (T (текст), H1), где H1 — алгоритм обработки текста T. Данная функция хеширует T таким образом, что без знания H1 открыть его как полноценный файл будет практически невозможно.

Использование хэш-функций на практике: скачивание файлов

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

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

Хэш-функция и ЭЦП

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

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

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

Проверка паролей

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

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

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

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

Коллизии хэш-функций

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

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

История появления


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

Популярные стандарты хеширования

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

В свою очередь, при шифровании достаточно широкое применение находят стандарты MD4 и MD5. Еще один популярный криптографический алгоритм — SHA-1. В частности, он характеризуется размером хэша 160 бит, что больше, чем у MD5 — данный стандарт поддерживает 128 бит. Есть российские стандарты, регулирующие использование хэш-функций, — ГОСТ Р 34.11-94, а также заменивший его ГОСТ Р 34.11-2012. Можно отметить, что величина хэша, предусмотренная алгоритмами, принятыми в РФ, составляет 256 бит.

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

Особенности алгоритма SHA

Применение хэш-функций, базирующихся на стандарте SHA, чаще всего осуществляется в области разработки средств цифровой подписи документов DSA. Как мы отметили выше, алгоритм SHA поддерживает хэш 160 бит (обеспечивая так называемый «дайджест» последовательности символов). Изначально рассматриваемый стандарт делит массив данных на блоки по 512 бит. При необходимости, если длина последнего блока не дотягивает до указанной цифры, структура файла дополняется 1 и необходимым количеством нулей. Также в конце соответствующего блока вписывается код, фиксирующий длину сообщения. Рассматриваемый алгоритм задействует 80 логических функций, посредством которых обрабатывается 3 слова, представленные в 32 разрядах. Также в стандарте SHA предусмотрено использование 4 констант.

Сравнение алгоритмов хеширования

Изучим то, как соотносятся свойства хэш-функций, относящихся к разным стандартам, на примере сопоставления характеристик российского стандарта ГОСТ Р 34.11-94 и американского SHA, который мы рассмотрели выше. Прежде всего, следует отметить то, что алгоритм, разработанный в РФ, предполагает осуществление 4 операций по шифрованию в расчете на 1 цикл. Это соответствует 128 раундам. В свою очередь, в течение 1 раунда при задействовании SHA предполагается вычисление порядка 20 команд, при том что всего раундов 80. Таким образом, использование SHA позволяет в течение 1 цикла обработать 512 бит исходных данных. В то время как российский стандарт способен осуществить операции за цикл в 256 бит данных.

Специфика новейшего российского алгоритма

Выше мы отметили, что стандарт ГОСТ Р 34.11-94 был заменен более новым — ГОСТ Р 34.11-2012 «Стрибог». Исследуем его специфику подробнее.

Посредством данного стандарта могут быть реализованы, как и в случае с алгоритмами, рассмотренными выше, криптографические хеш-функции. Можно отметить, что новейший российский стандарт поддерживает блок входных данных в объеме 512 бит. Основные преимущества ГОСТ Р 34.11-2012:

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

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

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

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

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

Итеративные схемы

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

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

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

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

Блочный алгоритм

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

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

Смысл функции hash() в HashMap (java 7 и java 8)

В Java 7 функция hash() класса HashMap имеет следующий вид:

Из всего этого я понимаю только первый комментарий (перед функцией). Данная функция используется «на всякий случай» — в случае, если hashCode объекта будет плохой («низкого качества»), то данная функция должна обеспечить лучший разброс значений. Это важно, потому что HashMap использует хэш-таблицы, размер которых — степень двойки (16, 32, 64 и т.д.), и в противном случае, при использовании хэш-кодов, у которых в младших битах есть совпадения (при использовании хэш-функций «низкого качества») возникают коллизии.

А что значит комментарий внутри функции?

This function ensures that hashCodes that differ only by constant multiples at each bit position have a bounded number of collisions (approximately 8 at default load factor).

И в чём собственно смысл преобразований функции?

Почему побитовые сдвиги и XOR — понятно, потому что данные операции выполняются быстрее, чем операции сложения и умножения. Но почему именно эти цифры (20, 12, 7, 4)? И каким образом эти преобразования делают более разнообразными младшие биты хэш-кодов?

И почему в Java 8 эта функция изменилась следующим образом?

В чём её смысл? Часть (key == null) ? 0 : вопросов не вызывает.

1 ответ 1

Для того, чтобы понять зачем HashMap модифицирует хеш объекта, нужно заглянуть под капот этого HashMap . Указанный ассоциативный массив реализуется через бакеты. HashMap состоит из массива таких бакетов, к которым можно обращаться по индексу. Количество бакетов — это всегда результат возведения 2 в какую-то степень ( 2, 4, 8, 16 и т.д.). Каждый из бакетов представляет из себя коллекцию (список или дерево). Хорошее распределение по HashMap — это когда каждый из бакетов содержит примерно одинаковое количество записей (пар ключ-значение)

Теперь к сути. При записи нового объекта сначала ищется бакет, в который будет производиться запись. Для этого берется остаток от деления хеша на количество бакетов (своего рода хеш от хеша). Это и будет индекс бакета, в который попадёт новый элемент. Для наглядности, операцию остаток от деления на результат степени 2-х (а это количество бакетов) можно представить в виде поразрядного И хеша и (количество_бакетов — 1) , т.е.:

Для примера покажу в двоичном варианте, где хэш равен 140 , а количество бакетов 32 (результат должен быть равен 12 ):

Тут и выползает интересная особенность. На то, в какой бакет попадёт новая запись, влияют только младшие биты хеша. При реальных условиях количество бакетов обычно невысокое (к примеру 8192 вмещается в 14 битов) . А хеш имеет тип int , т.е. аж 32 бита. .


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

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

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

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

Все это (или почти все) вы узнаете из этой маленькой заметки. Поехали.

Что такое хеш и хэширование простыми словами

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

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

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

Зачем нужен хэш

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

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

Илон Маск рекомендует:  Что такое код mb_convert_encoding

Где и как используют хеширование

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

А это, ведь на минутку, основной протокол передачи данных в сети интернет. Без него никуда. Да, есть вероятность, что произойдет накладка — их называют коллизиями. Ведь для разных изначальных данных может получиться один и тот же хеш. Чем проще используется функция, тем выше такая вероятность. Но тут нужно просто выбирать между тем, что важнее в данный момент — надежность идентификации или скорость работы. В случае TCP/IP важна именно скорость. Но есть и другие области, где важнее именно надежность.

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

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

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

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

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

Хочу систематизировать кое-что из уже сказанного и добавить новое.

  1. Как уже было сказано, функция эта должна уметь приводить любой объем данных (а все они цифровые, т.е. двоичные, как вы понимаете) к числу заданной длины (по сути это сжатие до битовой последовательности заданной длины хитрым способом).
  2. При этом малейшее изменение (хоть на один бит) входных данных должно приводить к полному изменению хеша.
  3. Она должна быть стойкой в обратной операции, т.е. вероятность восстановления исходных данных по хешу должна быть весьма низкой (хотя последнее сильно зависит от задействованных мощностей)
  4. В идеале она должна иметь как можно более низкую вероятность возникновения коллизий. Согласитесь, что не айс будет, если из разных массивов данных будут часто получаться одни и те же значения хэша.
  5. Хорошая хеш-функция не должна сильно нагружать железо при своем исполнении. От этого сильно зависит скорость работы системы на ней построенной. Как я уже говорил выше, всегда имеется компромисс между скорость работы и качеством получаемого результата.
  6. Алгоритм работы функции должен быть открытым, чтобы любой желающий мог бы оценить ее криптостойкость, т.е. вероятность восстановления начальных данных по выдаваемому хешу.

Хеш — это маркер целостности скачанных в сети файлов

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

Что это такое? И что вам с этим всем делать? Ну, как правило, на тех же сайтах можно найти пояснения по этому поводу, но я не буду вас утруждать и расскажу в двух словах. Это как раз и есть результаты работы различных хеш-функций (их названия приведены перед числами: CRC32, MD5 и SHA-1).

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

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

Популярные хэш-алгоритмы сжатия

  1. CRC32 — используется именно для создания контрольных сумм (так называемое избыточное кодирование). Данная функция не является криптографической. Есть много вариаций этого алгоритма (число после CRC означает длину получаемого хеша в битах), в зависимости от нужной длины получаемого хеша. Функция очень простая и нересурсоемкая. В связи с этим используется для проверки целостности пакетов в различных протоколах передачи данных.
  2. MD5 — старая, но до сих пор очень популярная версия уже криптографического алгоритма, которая создает хеш длиной в 128 бит. Хотя стойкость этой версии на сегодняшний день и не очень высока, она все равно часто используется как еще один вариант контрольной суммы, например, при скачивании файлов из сети.
  3. SHA-1 — криптографическая функция формирующая хеш-суммы длиной в 160 байт. Сейчас идет активная миграция в сторону SHA-2, которая обладает более высокой устойчивостью, но SHA-1 по-прежнему активно используется хотя бы в качестве контрольных сумм. Но она так же по-прежнему используется и для хранения хешей паролей в базе данных сайта (об этом читайте выше).
  4. ГОСТ Р 34.11-2012 — текущий российский криптографический (стойкий к взлому) алгоритм введенный в работу в 2013 году (ранее использовался ГОСТ Р 34.11-94). Длина выходного хеша может быть 256 или 512 бит. Обладает высокой криптостойкостью и довольно хорошей скоростью работы. Используется для электронных цифровых подписей в системе государственного и другого документооборота.

HashTab — вычисление хеша для любых файлов на компьютере

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

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

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

Чтобы не сравнивать контрольные суммы визуально, можно числа по очереди вставить в рассположенное ниже поле (со знаком решетки) и нажать на кнопку «Сравнить файл».


Как видите, все очень просто и быстро. А главное эффективно.

Hash function

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

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

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

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

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

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

Содержание

История [ | ]

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

Галилео Галилей наблюдал кольца Сатурна, которые принял за «ушки». Не будучи уверен, но желая утвердить свой приоритет, он опубликовал сообщение с перестановленными буквами: smaismrmilmepoetaleumibunenugttauiras. В 1610 году он раскрыл исходную фразу: Altissimum planetam tergeminum obseruaui, что в переводе с латинского языка означает «высочайшую планету тройною наблюдал». Таким образом, на момент публикации первого сообщения исходная фраза не была раскрыта, но была создана возможность подтвердить её позже.

В середине 1650-х Христиан Гюйгенс разглядел кольца и опубликовал сообщение с буквами, расставленными по алфавиту: ааааааа, ссссс, d, еееее, g, h, iiiiiii, lllll, mm, nnnnnnnnn, oooo, pp, q, rr, s, ttttt, uuuuu. Через некоторое время была опубликована и исходная фраза: Annulo cingitur, tenui plano, nusquam cohaerente, ad eclipticam inclinato — «Окружен кольцом тонким, плоским, нигде не подвешенным, наклоненным к эклиптике». От применения хеш-функции, включая и цель позднее подтвердить некоторое нераскрытое сообщение, данный случай отличается только тем, что выходное сообщение не имеет фиксированной длины, а определяется длиной входного. Фактически, расстановка букв исходного сообщения по алфавиту является некоторой хеш-функцией, но только с результатом нефиксированной длины.

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

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

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

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

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

Виды «хеш-функций» [ | ]

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

  • быстрое вычисление;
  • минимальное количество «коллизий».

Рассмотрим несколько простых и надёжных реализаций «хеш-функций».

hash function

Англо-русский толковый словарь терминов и сокращений по ВТ, Интернету и программированию. . 1998-2007 .

Смотреть что такое «hash function» в других словарях:

Hash function — A hash function is any well defined procedure or mathematical function for turning some kind of data into a relatively small integer, that may serve as an index into an array. The values returned by a hash function are called hash values, hash… … Wikipedia

hash function — A function that maps a data item to a numeric value by use of a transformation. A hash function can convert a number that has meaning to a user, such as a key or other >Dictionary of networking

hash function — maišos funkcija statusas T sritis informatika apibrėžtis Funkcija, iš duomenų ↑įrašo arba jo ↑rakto (1), apskaičiuojanti ↑maišos reikšmę. Funkcijos algoritmas priklauso nuo to, kam bus naudojama jos reikšmė. Pavyzdžiui, jeigu projektuojama įrašų… … Enciklopedinis kompiuterijos žodynas

hash function — one way function (not reversible) that changes input data in to a unique digital code (also used in information security as a digital signature that >English contemporary dictionary

hash function — noun an algorithm that generates a numeric, or fixed size character output from a variable sized piece of text or other data; used in database table queries, cryptography and in error checking … Wiktionary

Cryptographic hash function — A cryptographic hash function (specifically, SHA 1) at work. Note that even small changes in the source input (here in the word over ) drastically change the resulting output, by the so called avalanche effect. A cryptographic hash function is a… … Wikipedia

NIST hash function competition — Cryptography portal The NIST hash function competition is an open competition held by the US National Institute of Standards and Technology for a new SHA 3 function to replace the older SHA 1 and SHA 2, which was formally announced in the Federal … Wikipedia

Perfect hash function — A perfect hash function for a set S is a hash function that maps distinct elements in S to a set of integers, with no collisions. A perfect hash function has many of the same applications as other hash functions, but with the advantage that no… … Wikipedia

NIST hash function competition — La NIST hash function competition est une compétition organisée par la NIST afin de trouver une nouvelle fonction de hachage (SHA 3) destinée à remplacer les anciennes fonctions SHA 1 et SHA 2. Sommaire 1 Participants 1.1 Finalistes 1.2 … Wikipédia en Français

GOST (hash function) — The GOST hash function, defined in the standards GOST R 34.11 94 and GOST 34.311 95, is a 256 bit cryptographic hash function. It was initially defined in the Russia s national standard GOST R 34.11 94 Information Technology Cryptographic… … Wikipedia

The Hash Function Hamsi — Содержание 1 Краткое описание 2 История 3 The Hash Funtion Hamsi 3.1 Общая структу … Википедия

Строковые алгоритмы. Хэш-функция. (String Algorithms. Hash.)

Чтобы просмотреть это видео, включите JavaScript и используйте веб-браузер, который поддерживает видео в формате HTML5


Введение в биоинформатику

Half Faded Star

Курс «Введение в биоинформатику» адресован тем, кто хочет получить расширенное представление о том, что такое биоинформатика и как она помогает биологам и медикам в их работе. The course is aimed at those who would like to have a better idea of what bioinformatics is and how it helps biologists and medical scientists in research and clinical work.

Рецензии

Half Faded Star

Пятая неделя нашего курса посвящена выравниванию коротких фрагментов на референс — подходу, который используется при работе с уже изученными геномами. В лекциях разбираются наиболее популярные программы для решения таких задач, а также основные алгоритмы для работы со строками.
Fifth week of our course is devoted to short read alignment to the reference genome, which is used when we work with the already studied organisms. In lectures we will talk about the most popular software for solving such problems, as well as basic algorithms for working with strings.

Преподаватели

Alla L Lap >Professor, Department of Cytology and Histology

Николай Вяххи

Павел Добрынин

Михаил Райко

Екатерина Черняева

Текст видео

[ЗАСТАВКА] [ЗАСТАВКА] Здравствуйте. Сегодня мы поговорим о строковых алгоритмах, применяемых в информатике. И для начала введём определение, что такое алфавит. Алфавит — это набор некоторых символов, из которых складываются строки. Алфавит может быть разный. Может быть из букв а, б, в, г, д, и так далее, вплоть до я, это алфавит символов из кириллицы, может быть алфавит a, b, c, d, e, и так далее, вплоть до z, может быть алфавит, с которым мы чаще всего и будем работать, состоящий из букв A, C, G и T. Это алфавит из четырёх букв, соответствующих нуклеотидам в геноме. И геном или любая геномная последовательность — это слово в этом алфавите, которое составлено из букв этого алфавита. Бывают алфавиты и другие. Например, в лингвистике, часто используется алфавит из слов. И тогда слово — это предложение. И некоторые поисковые системы, и поисковые алгоритмы, которые работуют на текстах ищут не по отдельным буквам, а по целым словам, и тогда алфавит — это слова. В нашем случае часто используется алфавит именно из букв A, C, G и T. Также важно понимать различия между понятием «подстрока» и «подпоследовательность». Для начала также важно понимать, что строка и последовательность обозначают одно и то же, и я буду часто называть строки последовательностями и последовательности строками. Но подстрока и подпоследовательность — это разные математические термины. Подстрока — это когда некоторый. некоторое слово полностью содержится в тексте, в какой-то позиции этого текста. Подпоследовательность — это когда буквы из нашего слова встречаются в тексте в этом порядке. Например, если наш текст или геном — это ACGT ACGT, то, например, GTA является подстрокой этого текста, потому что она полностью встречается последовательно в некоторой позиции этого текста. Но GTC не является подстрокой, с другой стороны, оно является подпоследовательностью, потому что буквы G, T и C встречаются именно в той же последовательности, как и специфицировано в нашей строке. Теперь рассмотрим задачу о нахождении подстроки в строке, которую вкратце мы обсуждали и в прошлый раз, но сейчас мы рассмотрим более эффективные алгоритмы для решения этой задачи. Напомню, что нам дан некоторый текст, например, геном, и дан некоторый паттерн, например, рид, который мы хотим найти в этом геноме, то есть мы хотим найти такую позицию в этом геноме, где встречается наш рид. Что мы можем сделать? Мы можем прикладывать этот рид в каждой позиции, начиная с первой, и проверять точное совпадение. Допустим у нас текст длины M и рид длины K, тогда, чтобы найти приложение этого рида к геному, нам нужно совершить O от M на K операций, то есть каждую позицию рида сравнить с каждой позицией генома. Но можно сделать это и чуть более эффективно. Один из способов находить более эффективные подстроки в строке — это использовать хэширование. Это достаточно распространённая техника, которая применяется активно в строковых алгоритмах и на практике хорошо работает. И часто с помощью хэширования, с помощь применения Hash функции можно решить очень многие строковые алгоритмы достаточно эффективно, даже несмотря на то, что в худшем случае они бы работали дольше, но в среднем и на практике они работают очень хорошо. Для этого введём определение Hash функции. Hash функция — это некоторая функция, которая берёт объект из множества a и переводит его в объект из множества b, при этом важно, что множество b более маленькое, более компактное, чем a. Например, в данном случае мы можем ввести функцию Hash от строки, которая переводит строку в не которое число, например, складывает коды всех букв и это является числом. Понятно, что у разных строк может быть одинаковое значение Hash функции. Например, если мы просто складываем значения целочисленных букв, то Hash функция от строки AC будет равно Hash функции от строки CA. Но главное, что если Hash функция совпадает, то потенциально эти строки могут быть одинаковыми. И, в частности, именно Hash функция от строк в число чаще всего применяется в геномике. Как это можно использовать для нахождения подстроки в строке? Мы можем посчитать Hash функцию от нашего рида, то есть, допустим, Hash функция от рида нам известна, это некоторое целое число, которое мы посчитаем. Теперь мы можем считать Hash функцию от каждой подстроки в нашем геноме и сравнивать не целые строки, а значения Hash функций. И, если значения Hash функций равны, то после этого уже сравнивать сами строки. Вроде бы никакого ускорения в данном случае не получается, потому что, чтобы вычислить Hash функцию от каждой подстроки, нам нужно совершить те же K операций, умножить на M, и получается та же самая оценка O (M * K). Но Hash функцию можно вычислять более эффективно. Например, если у нас есть геном ACGT, ACGT, и мы знаем Hash функцию от некоторой подстроки этого генома ACG, то следующую Hash функцию от CGT мы можем вычислить быстро, не складывая все эти буквы, а, например, вычтя значение буквы A и прибавив значение буквы T. Таким образом пересчёт Hash функции по геному, когда мы идём, он будет происходить за O(1), то есть за одну, ну в данном случае две операции, одно вычитание и другое сложение, но это всё O(1), то есть это константа. И пересчитывая Hash функцию по геному мы можем быстро сравнивать потенциальное вхождение рида в этом месте генома. И если Hash функции равны, после этого уже сравнивать риды целиком. Конечно, у нас будут некоторые ложные срабатывания вот такого алгоритма, потому что, как я говорил ранее, значение Hash функции может совпадать случайно. Но это редкое событие и мы в любом случае проверяем потом точные вхождения. В частности, если мы вычислили Hash функцию в начале генома, потом во второй позиции генома, в третьей, и так далее, и в каком-то месте она совпала, мы после этого сравниваем всю последовательность рида с этим участком, если он не равен, мы двигаемся дальше. Допустим, Hash функция по значению совпала с нашим ридом здесь, и мы сравниваем снова полностью последовательность рида с этим частком в геноме, и если он равен, то это нужный нам ответ. Такой алгоритм в среднем работает за O(M + K), то есть нам нужно вычислить один раз Hash функцию от рида и начала генома, и потом M раз передвинуть эту Hash функцию, то есть пересчитывать для каждой следующей позиции за единичку, то есть 1*M. И такой алгоритм работает быстрее, и в среднем на практике он очень хорошо работает и хорошо применим. [ЗАСТАВКА]

Илон Маск рекомендует:  Эмуляторы j2me

Быстрая hash-функция

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

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

16 октября 2009

А чем это лучше вот этого:

Я знаю, зачем нужны hash функции, но у меня вопрос — в каких ситуациях эта дает более равномерный разброс?

Ну а как насчет критерия рассеивания? Будут ли у нее лучшие характеристики от додавания по модулю 2 или других простых методов? Как на сравнения рассеивания твоей ф-ции и метода деления на простое число? Скорость хеш функции не самый главный критерий.

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

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

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

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

Универсальное семейство хеш-функций

Содержание

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

Качественная хеш-функция (англ. hash function) удовлетворяет (приближенно) условию простого равномерного хеширования: для каждого ключа, независимо от хеширования других ключей, равновероятно помещение его в любую из [math] m [/math] ячеек. Но это условие обычно невозможно проверить, так как распределение вероятностей, с которыми поступают входные данные, как правило, неизвестно. К тому же, вставляемые ключи могут и не быть независимыми. Если наш противник будет умышленно выбирать ключи для хеширования при помощи конкретной хеш-функции, то при некоторых реализациях хеш-таблиц может получиться так, что все ключи будут записаны в одну и ту же ячейку таблицы, что приведет к среднему времени выборки [math] \Theta(n) [/math] . Таким образом, любая фиксированная хеш-функция становится уязвимой. И единственный эффективный выход из данной ситуации — случайный выбор хеш-функции. Такой подход называется универсальным хешированием. Он гарантирует хорошую производительность в среднем, вне зависимости от данных, выбранных нашим противником.

Определение:
Пусть [math] H [/math] — конечное множество хеш-функций, которые отображают пространство ключей [math]\ U [/math] в диапазон [math] \ <0, 1, 2, .. , m - 1\>[/math] . Такое множество называется универсальным (англ. universal), если для каждой пары ключей [math] k, l \in U, (k\ne l)[/math] количество хеш-функций [math] h \in H [/math] , для которых [math] h(k) = h(l) [/math] не превышает [math] \frac<|H|> [/math] .

Иными словами, при случайном выборе хеш-функции из [math] H [/math] вероятность коллизии между различными ключами [math] k, l [/math] не превышает вероятности совпадения двух случайным образом выбранных хеш-значений из множества [math] \ <0, 1, 2, .. , m - 1\>[/math] , которая равна [math] \frac<1> [/math] .

Построение универсального множества хеш-функций [ править ]

Доказательство: [math]\triangleright[/math]

Рассмотрим [math]k,l\in Z_p:k\ne l[/math] . Пусть для данной хеш-функции [math]h_[/math]

[math]r\ne s[/math] , так как [math]r-s\equiv a(k-l)\pmod p[/math] , а [math]p[/math] — простое число, [math]a[/math] и [math](k-l)[/math] не равны нулю по модулю [math]p[/math] . Значит, произведение [math]r[/math] и [math]s[/math] также отлично от нуля по модулю [math]p[/math] . Таким, образом, коллизии «по модулю [math]p[/math] » отсутствуют. Более того, каждая из [math]p(p-1)[/math] возможных пар [math](a,b)[/math] , приводят к различным парам [math](r,s):r\ne s[/math] . Чтобы доказать это, достаточно рассмотреть возможность однозначного определения [math]a[/math] и [math]b[/math] по заданным [math]r[/math] и [math]s[/math] :

[math]a=\left((r-s)((k-l)^<-1>\bmod p)\right)\bmod p,\ b=(r-ak)\bmod p[/math] .

Поскольку имеется только [math]p(p-1)[/math] возможных пар [math](r,s):r\ne s[/math] , то имеется взаимнооднозначное соответствие между парами [math](a,b)[/math] и парами [math](r,s):r\ne s[/math] . Таким образом, для любых [math]k,l[/math] при равномерном случайном выборе пары [math](a,b)[/math] из [math]Z_p^*\times Z_p[/math] , получаемая в результате пара [math](r,s)[/math] может быть с равной вероятностью любой из пар с отличающимися значениями по модулю [math]p[/math] .

Отсюда следует, что вероятность того, что различные ключи [math]k,l[/math] приводят к коллизии, равна вероятности того, что [math]r\equiv s\pmod m[/math] при произвольном выборе отличающихся по модулю [math]p[/math] значений [math]r[/math] и [math]s[/math] . Для данного [math]r[/math] имеется [math]p-1[/math] возможное значение [math]s[/math] . При этом число значений [math]s:s\ne r[/math] и [math]s\equiv r\pmod p[/math] , не превышает

Вероятность того, что [math]s[/math] приводит к коллизии с [math]r[/math] при приведении по модулю [math]m[/math] , не превышает [math]\frac\cdot\frac<1>=\frac<1>[/math] .

Значит, [math]\forall k\ne l\in Z_p\ P(h_(k)=h_(l))\le\frac<1>[/math] , что означает, что множество хеш-функций [math]H_[/math] является универсальным. [math]\triangleleft[/math]

Попарная независимость [ править ]


Определение:
Пусть [math] H [/math] — универсальное семейство хеш-функций. Говорят что оно обладает свойством попарной независимости(англ. pairwise independence), если при фиксированных [math] x, y[/math] [math] (0 \le x, y \le m-1)[/math] для каждой пары ключей [math] k, l \in U (k\ne l) [/math] вероятность того, что [math] h(k) = x [/math] и [math] h(l) = y [/math] , равна [math] \frac<1> + o(\frac<1>) [/math] .

Построение попарно независимого множества хеш-функций [ править ]

Доказательство: [math]\triangleright[/math]

Для функции [math]h_[/math] получаем

[math]x = (ak+b)\bmod p \bmod m[/math]

[math]y = (al+b)\bmod p \bmod m[/math]

Выразим отсюда [math]a[/math] и [math]b[/math] . Вычтя из первого уравнения второе, получим:

[math]x — y = a(k — l)\bmod p \bmod m[/math]

Теперь сначала первое домножим на [math]l[/math] , и второе на [math]k[/math] . Вычитаем:

[math]lx — ky = b(l — k)\bmod p \bmod m[/math]

[math]x — y \equiv a(k — l)+im \pmod p[/math]

[math]lx — ky \equiv b(l — k)+jm \pmod p[/math] ,

где [math] 0 \le i, j \lt \lfloor \frac

\rfloor [/math] .

Стоит отметить, что эти равенства мы считаем выполненными, если при данных [math]a, b, x[/math] и [math]y[/math] и каких-либо [math]i[/math] и [math]j[/math] они будут верными (исходя из того как мы их получили).

[math]k \ne l[/math] , [math]p[/math] — простое, тогда

[math]a \equiv (k — l)^<-1>(x — y — im) \pmod p[/math]

[math]b \equiv (l — k)^<-1>(lx — ky — jm)[/math] [math]\pmod p[/math]

Теперь заметим, что [math]a[/math] принимает [math]p[/math] различных значений, а [math]i[/math] — [math]\lfloor \frac

\rfloor[/math] значений. Понятно, что для заданных [math]x, y[/math] и [math]a[/math] с вероятностью лишь [math] \frac<1> [/math] найдётся [math]i[/math] , обращающий первое равенство в тождество; аналогично и со вторым равенством.

Остаётся подытожить наши выкладки.

[math]P( [x = (ak+b)\bmod p \bmod m][/math] [math]\wedge[/math] [math][y = (al+b)\bmod p \bmod m])[/math] [math]=[/math]

[math]=[/math] [math]P( [a \equiv (k — l)^<-1>(x — y — im)[/math] [math]\pmod p][/math] [math]\wedge[/math] [math][b \equiv (l — k)^<-1>(lx — ky — jm)[/math] [math]\pmod p])[/math] [math]=[/math]

[math]=[/math] [math]P( a \equiv (k — l)^<-1>(x — y — im)[/math] [math]\pmod p)[/math] [math]\cdot[/math] [math]P( b \equiv (l — k)^<-1>(lx — ky — jm)[/math] [math]\pmod p)[/math] [math]=[/math]

Функции mhash

Hash functions are by definition and implementation generally regarded as Pseudo Random Number Generators (PRNG). From this generalization it can be assumed that the performance of hash functions and comparisons between other hash functions can be determined by modeling the functions as PRNGs.

Analysis techniques such a Poisson distribution can be used to analyze the collision rates of different hash functions for different groups of data. In general there is a theoretical hash function known as the Perfect Hash Function for any specific group of data. The perfect hash function by definition states that no collisions will occur meaning no repeating hash values will arise from different elements of the group.

In reality it is very difficult to find a perfect hash function for an arbitrary set of data, and furthermore the practical applications of perfect hashing and its variant minimal perfect hashing are quite limited. So instead one may choose to pursue the concept of an Ideal Hash Function, which is commonly defined as a function that produces the least amount of collisions for a particular set of data.

One of the fundamental problems with hashing data or specifically mapping values from one domain to another, is that there are soo many permutations of types of data, some highly random, others containing high degrees of patterning or structure that it is difficult to generalize a hash function for all data types or even for specific data types. All one can do is via trial and error and utilization of formal hash function construction techniques derive the hash function that best suites their needs. Some factors to take into account when choosing hash functions are:

Data Distribution

This is the measure of how well the hash function distributes the hash values of elements within a set of data. Analysis in this measure requires knowing the number of collisions that occur with the data set meaning non-unique hash values, If chaining is used for collision resolution the average length of the chains (which would in theory be the average of each bucket’s collision count) analyzed, also the amount of grouping of the hash values within ranges should be analyzed.

In the following diagram there are five unique messages to be hashed (M. M4) and inserted into a hash-table. Each message is hashed using two different hash functions H1 and H2. The diagram depicts how H1 generally distributes the hash values for the messages evenly over the given bucket-space (table), where as H2 returns the same value for each message causing numerous collisions.

Hash Function Efficiency

This is the measure of how efficiently the hash function produces hash values for elements within a set of data. When algorithms which contain hash functions are analyzed it is generally assumed that hash functions have a complexity of O(1), that is why look-ups for data in a hash-table are said to be «on average of O(1) time complexity», where as look-ups of data in other associative containers such as maps (typically implemented as Red-Black trees) are said to be of O(logn) time complexity.

A hash function should in theory be a very quick, stable and deterministic operation. A hash function may not always lend itself to being of O(1) complexity, however in general the linear traversal through a string or byte array of data that is to be hashed is so quick and the fact that hash functions are generally used on primary keys which by definition are supposed to be much smaller associative identifiers of larger blocks of data implies that the whole operation should be quick, deterministic and to a certain degree stable.

The hash functions in this essay are known as simple hash functions or General Purpose Hash Functions. They are typically used for data hashing (string hashing). They are used to create keys which are used in associative containers such as hash-tables. These hash functions are not cryptographically safe, they can easily be reversed and many different combinations of data can be easily found to produce identical hash values for any combination of data.

Hashing Methodologies

When designing and implementing hash functions the common building blocks typically used are bitwise operations, mathematical operations and look-up tables. These operations are applied either to individual bytes or blocks of bytes (words etc), furthermore they are fast, deterministic and readily available on most CPU architecture, making them ideal for implementing hash functions. The following is a list of the commonly used operations:

  • Bitwise Operations: Not (!), Or (|), And (&), Xor (^), Shift-Left/Right ( >), Rotate-Left/Right ( >>)
  • Mathematical Operations: Addition (+), Multiplication (*)
  • Lookup Tables: List of prime numbers, List of magic numbers, S-Box, P-Box

A common method for constructing collision resistant cryptographic hash functions is known as the Merkle–Damgard construction. A simplified version of this method can be used to easily generate well performing general purpose hash functions. In this method a piece of data (message) is transformed into a hash value as follows:

  1. Initialise an internal state
  2. Consume the message N-bits at a time (aka block size typically 32-bits, 64-bits, 128-bits etc..)
  3. Perform a mixing operation with the current block and the internal state
  4. Update the internal state with the the result of [3]
  5. If there are any remaining bytes in the message proceed to [2]
  6. Finalize the internal state and return the hash value


Note: The term Internal State (IS), depicted in the diagram as red circles, refers to a piece of memory, that is to be at least as large as the number of bits expected in the hash value. The IS at the start of the hash function will be initialised with a predetermined value — this is typically known as the Initialisation Vector (IV). The IS is primarily used during the mixing process and can generally be thought of as the final state of the hash function after the previous round. Its use in the mixing process is to create a data dependency between the result of the mix with the current message block and the results of the mixes from all the preceding message blocks. This process is commonly referred to as: Chaining

Note: The term Finalize means to take the internal state and prepare the final hash value that will be returned from the function. In the event the IS contains more bits than is required for the hash value, the IS itself will undergo a mixing process that will result in a value that is size compatible with the hash value type. Some implementations will also attempt to integrate side information such as the total number of bits hashed, or mixes with magic numbers based on the final value of the IS.

The «Mix» operation denoted above takes as input the internal state and the current message block, performs some computation and returns the value of the internal state. The following is a pseudo code example of a possible implementation of «Mix», that operates on blocks and internal state of size 32-bits at a time:

The «Mix» operation denoted above, will compute the multiplication between the current message block and the internal state, it will then proceed compute the sum of the internal state shifted by three bits to the left and the message block shifted by two bits to the right, then it will bitwise xor the first computation with the second and return that value as the result of the mix.

Putting it all together requires looping over all of the message 32-bits at-a-time, performing the mix operation upon each block, updating the internal state and taking care of any remainder bits after the main loop has completed. The resulting hash function will generally look like the following:

Lookup Tables (LUTs)

Various hash function designs utilize look-up tables within their mixing process. The reasons for using LUTs are varied but primarily seem to center around the ability to increase the variance of «static values» used within the fundamental mixing operation.

In the mix process defined above there are two static values 2 and 3, being used — if one where to utilize a LUT of values, then perhaps as an example a different value can be used on each round, rather than just the values 2 and 3 for each and every round.

When LUTs are employed in a hash function they are typically used in a combination of one or more of the following ways:

  • Lookup per round index
  • Lookup per internal state
  • Lookup per current message

Given a LUT named P, the various ways P can be used to generate the next state of the hash via the mixing process based on the above list of possible operations are as follows:

Where: Hi, Hi+1 are the current and next internal states respectively, roundi is the index of the current mixing round, Blocki is the block of the message in the current mixing round and |P| is the size of the lookup table.

As far as the composition of the LUTs are concerned, the types of values (numbers) used are typically implementation defined. Sometimes they may be a list of prime numbers, other times they may be a set of values that possess specific bit patterns (eg: 0xA5A5A5A5 etc), or they may simply just be a list of randomly selected numbers (Nothing up my sleeve numbers) .

In the design of cryptographic hash functions and ciphers, the construction of S-Boxes and P-Boxes have become a well studied area. If one is looking to implement a general purpose hash function based on utilizing a list of values during the mixing process, a review of the literature associated with S-Box and P-Box design techniques would be highly recommendable.

The following are some general recommendations to consider when implementing a hash function:

    Recommendation 1: The «mix» operation does not need to be the same on each round. There could be multiple mix operations which are selected based on criteria such as the index of the current round, the value of the internal state etc.

Recommendation 2: When hashing large messages, one could break the message up into chunks and compute the hash of each chunk in parallel then aggregate the hashes using a mix operation, this will dramatically increase the throughput of the hash function when running upon architectures that support multiple cores. This method of hashing is known as a Merkle-Tree or a hash-tree.

Recommendation 3: The operations present in the Mix should be carefully chosen, as more often than not the mixing process may result in lowering the entropy of the internal state to the point where the internal state does not change. As an example in the mix operation denoted above if the internal state reaches the value ZERO it will typically end-up returning zero.

Recommendation 4: The mix operation should handle repeated values in the message block, without causing a «flush effect on the internal state. A typical scenario might be a message comprised of bytes with the value of zero.
Question: how many consecutive zero bytes will it take to get the internal state of the hash function to become zero? The answer for a well designed hash function should be: A-LOT.

  • Recommendation 5: When hashing a key derived-from or otherwise aliasing a pointer to memory that has been obtain from an allocator that returns aligned addresses, one will observe that the first 2 or 3 Least Significant Bits (LSBs) of the key will always be zero, or in other words will have zero entropy. This is due to the fact that the pointers will be storing addresses that are multiples of either 4 or 8 depending on the machine’s addressing granularity. The following are a couple of techniques to resolve the issue of low-entropy LSBs:
    • Fill in the LSBs with bits from their higher order neighbours: pointer |= (pointer >> 3) & 0x03
    • Fill in the LSBs with bits from a LUT: pointer |= lut[round_i % lut_size] & 0x03
  • Hash Functions and Prime Numbers

    Generally speaking there is a rich tapestry of fact and fiction when it comes to the use of prime numbers in hash functions. Prime numbers are typically used in two areas regarding hash function implementation, they are:

    • Hash value quantisation
    • Mixing and entropy boosting

    Hash Value Quantisation Using Prime Numbers

    This area is by far the most reasonable and contains mathematically solid explanations for the use of prime-numbers under certain situations. The problems that arise here are typically related to the Pigeonhole Principle.

    When using a hash function as part of a hash-table, one will want to quantize or in other words reduce the hash value to be within the range of the number of buckets in the hash-table. It is assumed that a good hash functions will map the message m within the given range in a uniform manner. The quantisation of the hash value is efficiently and simply obtained by computing the hash value modulus the table size N, as follows:

    The result of this operation will be a value H in the range R defined as [0, N).

    Problem 1 — Non-Uniform Mappings

    Because the size of the table N will typically be smaller than the maximum value of the hash function Hmax (hence the requirement for quantization) and Hmax will most likely not be a multiple of N, nor will N likely be a factor or a multiple of a factor of Hmax, the first (Hmax mod N) values in the range will have a higher probability of having values hashed to them when compared to the remaining values in the range. So rather than having a value be mapped to any of those buckets with equal probability of 1/N, they will instead be mapped with a probability of 2/N, which is twice that of the other buckets. This will result in a higher load factor (collision rate) for the first (Hmax mod N) buckets in the table.

    As an example assume we have a good hash function h(x) that uniformly maps keys in the range [0,15] as H and a hash-table with only 10 buckets, we may simply quantize the hash values as follows:


    The problem, assuming uniformly distributed keys in the range [0,15], is that the buckets [0,5] will have a higher probability of having values mapped to them when compared to the other buckets in the range [6,9].

    Simply put this particular problem can’t be resolved by using prime numbers as the quantisation value. That being said there are a couple of things that can be done to resolve or mitigate this problem, they are as follows:

    • Set the hash table size to be a factor of Hmax (eg: A good basis would be 2 n )
    • Increase the hash table size (where possible have the size tend closer to Hmax)

    Note: This problem also appears when generating random numbers within a specified range, where the underlying random number generator generates values in a range that is larger than and is not a multiple of the desired range.

    Problem 2 — Non-Uniformly Distributed Keys And Factors of N (Table Size)

    N is the number of buckets in a hash table and as such is commonly used as the quantisation value. There is an issue which can arise if the keys being hashed are not uniformly distributed. Specifically when the keys result in values before quantisation that are factors or multiples of factors of N. In this situation buckets that aren’t factors of N or multiples of factors of N will remain empty, causing the load factor of the other buckets to increase disproportionately.

    This situation seems to be the only valid reason to use a prime number as a quantisation value. Given that a prime number has only itself and one as factors, using a prime number to resolve this problem means even if the keys are not uniformly distributed and instead possess some of kind structure (specifically multiples of a value etc), the likelihood that those values will arbitrarily hash to either the value one or N (the prime number) will be vanishingly small.

    Example: Lets assume we have a set of 30 messages M, M1, . M29, where we proceed to hash each message using a well behaved hash function h(x). This gives us the values H, H1, . H29, which so happened to be in the form: 30, 33, 36, 39, 42, 45, . ,111, 114, 117 — essentially all are multiples of three.

    Furthermore we have a hash table with 21 (3×7) buckets or in other words a hash-space in the range [0,20]. We dec >

    Now if we had instead chosen a prime number, for example 23, we would have utilized each and every one of the buckets in the table and would have only had 7 collisions — which would also be the theoretical minimum number of possible collisions given the table size (bucket-space).

    One further thing to consider would be that instead of a prime number we could have chosen a composite number that does not have three as one of its factors. But we would then also have to guarantee that none of the multiples of three, which we intend to quantise, are also not one of its factors — in short the problem becomes very hairy very quickly for little to no gain — Q.E.D

    That being said, this particular solution has a slight overhead of its own — that is once a maximum table load factor has been reached the table will need to be re-sized. This is typically achieved by simply doubling the size of the current table, but one must also remember to snap to the next largest prime number as the new size, rather than simply doubling the current size.

    In conclusion it would be far more productive and effective to mix the keys more thoroughly and rigorously than it would be to faff around with the ever changing quantisation parameter. Using something as simple as a power of two (2 n ) will generally suffice, given a satisfactory mixing process and relatively well distributed keys [Mitzenmacher et al. 2011].

    Mixing And Entropy Boosting Using Prime Numbers

    This area is where most of the mythology surrounding the use of prime numbers in hash functions reside. In implementing the mixing operation, one tries to define a process where by all the bits of the message block, equally affect all the bits of the internal state.

    As an example using a well designed hash function, given two messages that differ by only one bit, the expectation is that the hash values will be starkly different (aka having a large hamming distance). This property is derived from the Bit Independence Criterion (BIC) — cryptographic hash functions typically posses this trait, whereas general purpose hash functions don’t necessarily need to have this trait (as it’s largely an unrequired overhead), but instead attempt to attain something similar or close to BIC.

    The use of prime numbers in the mixing function, is due to an assumption that fundamental mathematical operations (such as addition and multiplication) with prime numbers «generally» result in numbers who’s bit biases are close to random.

    In simple terms the «theory» states that when you multiply (or add) a set of random numbers (aka keys) by a prime number the resulting numbers when as a group statistically analyzed at their bit levels should show no (or very little) bias towards being one state or another ie: Pr(Bi = 1)

    There is no concrete proof or other forms of evidence to support that this is the case or that it only (or more often) happens with prime numbers as opposed to composite numbers. It just seems to be an ongoing self-proclaimed intuition that some professionals in the field seem obliged to follow and preach.

    Bit Biases

    Bit sequence generators, be they purely random or in some way deterministic, will generate bits with a particular probability of either being one state or another — this probability is known as the Bit Bias. In the case of purely random generators the bit bias of any generated bit being high or low is always 50% (Pr = 0.5).

    However in the case of pseudo random number generators (PRNG), the algorithm generating the bits will define the bit bias of the bits generated in the minimal output block of the generator.

    Example: Let’s assume a PRNG that produces 8-bit blocks as its output. For some reason the MSB is always set to high, the bit bias then for the MSB will be a probability of 100% being set high. From this one concludes that even though there are 256 possible values that can be produced with this PRNG, values less than 128 will never be generated. Assuming for simplicity that the other bits being generated are purely random, then there is an equal chance that any value between 128 and 255 will be generated, however at the same time, there is 0% chance that a value less than 128 will be produced.

    All PRNGs, be they the likes of hash functions, ciphers, m-sequences or anything else that produces a bit sequence will all exhibit some form of bit bias. Most PRNGs will attempt to converge their bit biases to an equality, stream ciphers are one example, whereas others will work best with a known yet unstable bit bias.

    Mixing or scrambling of a bit sequence is one way of producing a common equality in the bit bias of a stream. Though one must be careful to ensure that by mixing they do not further diverge the bit biases. A form of mixing used in cryptography is known as avalanching, this is where a block of bits are mixed together sometimes using a substitution or permutation box (S-Box, P-Box), with another block to produce an output that will be used to mix with yet another block.

    As displayed in the figure below the avalanching process begins with one or more pieces of binary data. Bits in the data are taken and operated upon (usually some form of input sensitive bit reducing bitwise logic) producing an ith-tier piece data. The process is then repeated on the ith-tier data to produce an i+1’th tier data where the number of bits in the current tier will be less than or equal to the number of bits in the previous tier.

    The culmination of this repeated process will result in one bit whose value is said to be dependent upon all the bits from the original piece(s) of data. It should be noted that the figure below is a mere generalisation of the avalanching process and need not necessarily be the only form of the process.

    In data communications that use block code based error correcting codes, it has been seen that to overcome burst errors, that is when there is a large amount of noise for a very short period of time in the carrier channel, if one were to bit-scramble whole code blocks with each other, then have the scrambled form transmitted and then descrambled at the other end that burst errors would then most likely be distributed almost evenly over the entire sequence of blocks transmitted allowing for a much higher chance of fully detecting and correcting all the incurred errors. This type of deterministic scrambling and descrambling without the need for a common key is known as interleaving and deinterleaving.

    Various Forms Of Hashing

    Hashing as a tool to associate one set or bulk of data with an identifier has many different forms of application in the real-world. Below are some of the more common uses of hash functions.

    String Hashing

    Used in the area of data storage access. Mainly within indexing of data and as a structural back end to associative containers(ie: hash tables)

    Cryptographic Hashing

    Used for data/user verification and authentication. A strong cryptographic hash function has the property of being very difficult to reverse the result of the hash and hence reproduce the original piece of data. Cryptographic hash functions are used to hash user’s passwords and have the hash of the passwords stored on a system rather than having the password itself stored. Cryptographic hash functions are also seen as irreversible compression functions, being able to represent large quantities of data with a signal ID, they are useful in seeing whether or not the data has been tampered with, and can also be used as data one signs in order to prove authenticity of a document via other cryptographic means.

    Geometric Hashing

    This form of hashing is used in the field of computer vision for the detection of classified objects in arbitrary scenes.

    The process involves initially selecting a region or object of interest. From there using affine invariant feature detection algorithms such as the Harris corner detector (HCD), Scale-Invariant Feature Transform (SIFT) or Speeded-Up Robust Features (SURF), a set of affine features are extracted which are deemed to represent said object or region. This set is sometimes called a macro-feature or a constellation of features. Depending on the nature of the features detected and the type of object or region being classified it may still be possible to match two constellations of features even though there may be minor disparities (such as missing or outlier features) between the two sets. The constellations are then said to be the classified set of features.

    A hash value is computed from the constellation of features. This is typically done by initially defining a space where the hash values are intended to reside — the hash value in this case is a multidimensional value normalized for the defined space. Coupled with the process for computing the hash value another process that determines the distance between two hash values is needed — A distance measure is required rather than a deterministic equality operator due to the issue of possible disparities of the constellations that went into calculating the hash value. Also owing to the non-linear nature of such spaces the simple Euclidean distance metric is essentially ineffective, as a result the process of automatically determining a distance metric for a particular space has become an active field of research in academia.

    Typical examples of geometric hashing include the classification of various kinds of automobiles, for the purpose of re-detection in arbitrary scenes. The level of detection can be varied from just detecting a vehicle, to a particular model of vehicle, to a specific vehicle.


    Bloom Filters

    A Bloom filter allows for the «state of existence» of a large set of possible values to be represented with a much smaller piece of memory than the sum size of the values. In computer science this is known as a membership query and is a core concept in associative containers.

    The Bloom filter achieves the storage efficiency through the use of multiple distinct hash functions and by also allowing the result of a membership query for the existence of a particular value to have a certain probability of error. The guarantee a Bloom filter provides is that for any membership query there will never be any false negatives, however there may be false positives. The false positive probability can be controlled by varying the size of the table used for the Bloom filter and also by varying the number of hash functions.

    Subsequent research done in the area of hash functions and their use in bloom filters by Mitzenmacher et al. suggest that for most practical uses of such constructs, the entropy in the data being hashed contributes to the entropy of the hash functions, this further leads onto theoretical results that conclude an optimal bloom filter (one which provides the lowest false positive probability for a given table size or vice versa) providing a user defined false positive probability can be constructed with at most two distinct hash functions also known as pairwise independent hash functions, greatly increasing the efficiency of membership queries.

    Bloom filters are commonly found in applications such as spell-checkers, string matching algorithms, network packet analysis tools and network/internet caches.

    Consistent Hashing

    In consistent hashing, the hash space is broken into address ranges of roughly equal length. Each range is associated with one or more nodes, which hold values for keys that hash into that address range. By using a Global Hash Function, one can query the address space to determine the node(s) that will be holding the data corresponding to the key and then subsequently query the node directly for the required data.

    Typically nodes in adjacent addresses will replicate the closer half of keys from their neighbours on both sides, and in some situations nodes may also replicate a randomly selected node in the ring (random graph approach). This replication is done to provide resilience against node failures and allow for load balancing and overall latency reductions when data that hashes to a particular node is highly sought after or queried by many clients. This data structure is the principle component of Distributed Hash Tables (DHT).

    In the diagram below, the blue segmented ring represents the address space for the range of values the hash function (GH) can produce. Each segment, which denotes an address range, will have one more nodes associated with it, and when a client with a key wants to look up the corresponding data, they first invoke the GH which will give them the address range, they then look up the node(s) handling that address range using a directory service (obtain node’s IP address or routing ID etc), then proceed to directly query them using the key.

    Proof Of Work

    Cryptographic hash functions that are pre-image resistant, can be used in specific ways to verify that a certain amount or type of work has been carried out, this is commonly known as Proof Of Work, and makes up the fundamental basis of such things as crypto-currencies, challenge response hand-shakes etc.

    The way it typically works, is a known value K is given (some number of bits), then either an expected hash value or a hash value with a specific trait (eg: certain number of leading zero bits) is proposed.

    The applicant (aka entity performing the work) will then go off and perform a computation to determine another piece data D, such that H(K | D) (the hash of the concatenation of K and D) will either be equal to the expected hash value or will posses the properties required to prove the work has been done. Furthermore because the verification of the hash value can be performed cheaply and efficiently and the work in computing the value D itself must be done in full (as currently there are no known shortcuts — theoretic or otherwise), makes the use of such hash functions for POW style protocols an optimal choice.

    Available Hash Functions

    The General Hash Functions Library has the following mix of additive and rotative general purpose string hashing algorithms. The following algorithms vary in usefulness and functionality and are mainly intended as an example for learning how hash functions operate and what they basically look like in code form.

    00 — RS Hash Function

    A simple hash function from Robert Sedgwicks Algorithms in C book. I’ve added some simple optimizations to the algorithm in order to speed up its hashing process.

    01 — JS Hash Function

    A bitwise hash function written by Justin Sobel

    02 — PJW Hash Function

    This hash algorithm is based on work by Peter J. Weinberger of AT&T Bell Labs. The book Compilers (Principles, Techniques and Tools) by Aho, Sethi and Ulman, recommends the use of hash functions that employ the hashing methodology found in this particular algorithm.

    03 — ELF Hash Function

    Similar to the PJW Hash function, but tweaked for 32-bit processors. It is a widley used hash function on UNIX based systems.

    04 — BKDR Hash Function

    This hash function comes from Brian Kernighan and Dennis Ritchie’s book «The C Programming Language». It is a simple hash function using a strange set of possible seeds which all constitute a pattern of 31. 31. 31 etc, it seems to be very similar to the DJB hash function.

    05 — SDBM Hash Function

    This is the algorithm of choice which is used in the open source SDBM project. The hash function seems to have a good over-all distribution for many different data sets. It seems to work well in situations where there is a high variance in the MSBs of the elements in a data set.

    06 — DJB Hash Function

    An algorithm produced by Professor Daniel J. Bernstein and shown first to the world on the usenet newsgroup comp.lang.c. It is one of the most efficient hash functions ever published.

    07 — DEK Hash Function

    An algorithm proposed by Donald E. Knuth in The Art Of Computer Programming Volume 3, under the topic of sorting and search chapter 6.4.

    08 — AP Hash Function

    An algorithm produced by me Arash Partow. I took ideas from all of the above hash functions making a hybrid rotative and additive hash function algorithm. There isn’t any real mathematical analysis explaining why one should use this hash function instead of the others described above other than the fact that I tired to resemble the design as close as possible to a simple LFSR. An empirical result which demonstrated the distributive abilities of the hash algorithm was obtained using a hash-table with 100003 buckets, hashing The Project Gutenberg Etext of Webster’s Unabridged Dictionary, the longest encountered chain length was 7, the average chain length was 2, the number of empty buckets was 4579.

    Note: For uses where high throughput is a requirement for computing hashes using the algorithms described above, one should consider unrolling the internal loops and adjusting the hash value memory foot-print to be appropriate for the targeted architecture(s).

    General Hash Function License

    Free use of the General Hash Functions Algorithm Library available on this site is permitted under the guidelines and in accordance with the MIT License.

    Compatibility

    The General Hash Functions Algorithm Library C and C++ implementation is compatible with the following C & C++ compilers:

    • GNU Compiler Collection (3.3.1-x+)
    • Intel® C++ Compiler (8.x+)
    • Clang/LLVM (1.x+)
    • Microsoft Visual C++ Compiler (8.x+)

    The General Hash Functions Algorithm Library Object Pascal and Pascal implementations are compatible with the following Object Pascal and Pascal compilers:

    • Borland Delphi (1,2,3,4,5,6,7,8,2005,2006)
    • Free Pascal Compiler (1.9.x)
    • Borland Kylix (1,2,3)
    • Borland Turbo Pascal (5,6,7)

    The General Hash Functions Algorithm Library Java implementation is compatible with the following Java compilers:

    • Sun Microsystems Javac (J2SE1.4+)
    • GNU Java Compiler (GJC)
    • IBM Java Compiler
    Илон Маск рекомендует:  Введение в wml
    Понравилась статья? Поделиться с друзьями:
    Кодинг, CSS и SQL