Подтвердить что ты не робот

Как написать хэш-функцию в C?

Таблицы Hash считаются самым быстрым/лучшим способом хранения/получения данных.

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

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

У меня вопрос:

Является ли хеш-функция, используемая для хранения/извлечения данных DIFFERENT из криптографическая хэш-функция, используемая в приложениях безопасности для аутентификации как MD5, HMAC, SHA-1 и т.д...?

Чем они отличаются?

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

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

4b9b3361

Ответ 1

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

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

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

// warning: untested code.
size_t hash(char const *input) { 

    const int ret_size = 32;
    size_t ret = 0x555555;
    const int per_char = 7;

    while (*input) { 
        ret ^= *input++;
        ret = ((ret << per_char) | (ret >> (ret_size - per_char));
   }
   return ret;
}

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

Ответ 2

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

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

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

Ответ 3

Цели дизайна разные.

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

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