Хеш-функция — это алгоритмическое преобразование, которое принимает входные данные произвольного размера (ключ) и возвращает фиксированное по размеру значение (хеш), обычно целое число. В контексте Go и компьютерных наук в целом хеш-функции играют ключевую роль в реализации структур данных, таких как map, а также в криптографии, кэшировании и других областях.
Основные свойства хеш-функций
- Детерминированность: Для одного и того же входа всегда возвращается одинаковый хеш
- Равномерное распределение: Выходные значения должны равномерно распределяться по всему диапазону возможных значений
- Фиксированный размер вывода: Независимо от размера входа, выход всегда имеет одинаковую длину
- Эффективность: Быстрое вычисление для любых входных данных
Пример простой хеш-функции
func simpleHash(key string) uint32 {
var hash uint32
for _, c := range key {
hash = hash*31 + uint32(c)
}
return hash
}
Хеш-функции в Go
В Go хеш-функции используются в нескольких контекстах:
- Встроенные map: Для определения позиции элемента в хеш-таблице
- Пакет
hash
: Предоставляет интерфейсы для различных хеш-алгоритмов
- Криптография: В пакетах
crypto/sha256
, crypto/md5
и др.
Требования к хеш-функциям для map
- Стабильность: Один и тот же ключ должен давать одинаковый хеш в течение всего времени работы программы
- Хорошее распределение: Минимизация коллизий (разных ключей с одинаковым хешем)
- Быстрота вычисления: Так как хеширование происходит при каждой операции с map
- Защита от DoS: В современных версиях Go используется рандомизированное хеширование
Хеш-коллизии
Коллизия возникает, когда разные ключи дают одинаковый хеш. В Go это решается двумя способами:
- Цепочки (separate chaining): Каждая корзина (bucket) может содержать несколько элементов
- Открытая адресация: Поиск следующей доступной корзины при коллизии
Пример работы хеш-функции в map
package main
import (
"fmt"
"unsafe"
)
func main() {
m := make(map[string]int)
m["hello"] = 42
// На низком уровне происходит примерно следующее:
// 1. Вычисляется хеш от ключа "hello"
// 2. По хешу определяется корзина
// 3. Значение сохраняется в корзину
}
Криптографические vs не-криптографические хеш-функции
Характеристика |
Криптографические |
Не-криптографические |
Примеры |
SHA-256, MD5 |
FNV, MurmurHash |
Скорость |
Медленные |
Быстрые |
Безопасность |
Защищены от обратного преобразования |
Нет такой гарантии |
Использование |
Безопасность данных |
Структуры данных |
Резюмируем
- Хеш-функция преобразует данные произвольного размера в фиксированный хеш
- В Go используются для map, кэширования и других задач
- Должны быть быстрыми, детерминированными и давать равномерное распределение
- Коллизии решаются через цепочки или открытую адресацию
- Выбор хеш-функции зависит от конкретного использования (криптография vs структуры данных)