Ответ
Криптографическая хеш-функция — это математический алгоритм, который преобразует произвольный массив данных в строку фиксированной длины (хеш).
Ключевые свойства:
-
Детерминированность (Determinism): Один и тот же ввод всегда даёт один и тот же хеш.
-
Необратимость (Pre-image resistance): По известному хешу практически невозможно восстановить исходные данные. Это свойство критически важно для хранения паролей.
-
Стойкость к коллизиям (Collision resistance): Практически невозможно найти два разных набора входных данных, которые бы давали одинаковый хеш. Это важно для проверки целостности данных.
-
Лавинный эффект (Avalanche effect): Минимальное изменение во входных данных (например, одного бита) приводит к кардинальному, непредсказуемому изменению хеша.
-
Высокая скорость вычисления: Хеш должен вычисляться быстро для любого объёма данных.
Примеры использования в бэкенде:
- Хранение паролей: В базе данных хранятся не сами пароли, а их хеши (часто с "солью" — случайной строкой, уникальной для каждого пользователя).
- Проверка целостности данных: Для проверки того, что файл или сообщение не были изменены при передаче, можно сравнить хеш оригинала с хешем полученных данных.
- Ключи в структурах данных: Хеш-функции (не обязательно криптографические) лежат в основе
mapв Go для быстрого доступа к элементам. - Кэширование: Хеш от URL-адреса и параметров запроса может использоваться в качестве ключа для кэширования ответа.
- Цифровые подписи: Хеш документа подписывается приватным ключом для подтверждения авторства и неизменности.
Пример хеширования в Go (SHA-256):
package main
import (
"crypto/sha256"
"fmt"
)
func main() {
data := []byte("hello, backend!")
// Вычисляем хеш
hash := sha256.Sum256(data)
// Выводим хеш в виде шестнадцатеричной строки
fmt.Printf("%xn", hash)
} Ответ 18+ 🔞
Да ты посмотри, что за магия, блядь! Криптографическая хеш-функция — это как такой волшебный мясорубка, сука. Засовываешь туда что угодно: хоть "Войну и мир", хоть фотку своей тёщи — а на выходе получаешь, блядь, аккуратную строчку фиксированной длины. Вот эта строчка и есть хеш, ёпта.
И что она умеет, эта твоя мясорубка?
-
Детерминированность: Это как с водкой, чувак. Один и тот же огурец, закинутый в одну и ту же банку, всегда даст один и тот же рассол. И с хешом так же — один и те же данные на входе = один и тот же хеш на выходе. Никаких сюрпризов.
-
Необратимость: А вот это, сука, самое главное! Это как попытаться из котлеты восстановить, блядь, целую корову. По хешу нельзя понять, что было на входе. Именно поэтому пароли в базах хранят в виде хешей, а не в открытую, как дурачки. Иначе любой долбоёб, доставший базу, всех твоих пользователей по полочкам разложит.
-
Стойкость к коллизиям: Это значит, что практически невозможно найти два РАЗНЫХ куска данных, которые на выходе дадут ОДИН И ТОТ ЖЕ хеш. Представь, ты подписываешь договор на миллион, а злоумышленник находит другой текст, который даёт такую же подпись. Пиздец, да? Вот чтобы этого не было.
-
Лавинный эффект: Это вообще песня! Изменишь в исходных данных хоть одну запятую, одну буковку — и хеш меняется настолько пиздецки кардинально, что связи между старым и новым не найдёшь, даже если обосрёшься. Как будто взрыв, ёпта.
-
Скорость: Ну и, понятное дело, ждать, пока эта мясорубка пережуёт гигабайты логов, никто не будет. Всё должно работать быстро, как по маслу.
И где это всё, блядь, применяется?
- Пароли: Я уже говорил. Не храним пароли, храним их хеши, да ещё и с "солью" (это такая случайная приправа для каждого пользователя, чтобы одинаковые пароли выглядели по-разному).
- Целостность данных: Скачал ты файл, вычислил его хеш и сравнил с тем, что на сайте написали. Совпало? Значит, никто по дороге не подменил тебе в архив порнухи. Не совпало? Качай заново, тебя наебали.
- Внутри map в Go: Да-да, обычные
mapтоже на хешах работают, чтобы быстро ключи искать. Правда, там функции попроще. - Кэширование: Сделал хеш от URL и параметров запроса — вот тебе и идеальный ключ для кэша. Короткий и уникальный.
- Цифровые подписи: Сначала от документа делают хеш (быстро и коротко), а потом уже этот хеш подписывают секретным ключом. Экономия времени и места — овердохуищная.
Ну и как это выглядит в коде, на Go? Да элементарно, Ватсон!
package main
import (
"crypto/sha256"
"fmt"
)
func main() {
data := []byte("hello, backend!") // Суём в мясорубку нашу фразу
// Крутим ручку мясорубки (вычисляем хеш)
hash := sha256.Sum256(data)
// Смотрим, что на выходе получилось (в шестнадцатеричном виде)
fmt.Printf("%xn", hash)
}
Запустишь — и тебе вывалится эта самая строчка, уникальный отпечаток твоих данных. Красота, блядь! Всё гениальное просто, как три копейки.