Генерация уникального хеша из строки на JavaScript

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для получения хеша строки с помощью алгоритма SHA-256 в JavaScript, можно воспользоваться методом SubtleCrypto.digest() из Web Crypto API:

JS
Скопировать код
async function getSHA256Hash(str) {
  const buf = new TextEncoder().encode(str);
  const digest = await crypto.subtle.digest('SHA-256', buf);
  return Array.from(new Uint8Array(digest))
    .map(b => b.toString(16).padStart(2, '0'))
    .join('');
}
// Вот так можно этот код применить:
getSHA256Hash('example').then(console.log); // Выведет уникальный хеш для строки 'example'

В данном примере код отрабатывает вычисление SHA-256 хеша строки, а затем возвращает его в шестнадцатеричном представлении.

Кинга Идем в IT: пошаговый план для смены профессии

Методы хеширования на клиентской стороне

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

Использование String.prototype.hashCode

Этот способ создания хеша из строки подходит для выполнения клиентских задач:

JS
Скопировать код
String.prototype.hashCode = function() {
  let hash = 0;
  for (let i = 0; i < this.length; i++) {
    const chr = this.charCodeAt(i);
    hash = ((hash << 5) – hash) + chr;
    hash |= 0; // Преобразовываем к 32-битному целому числу
  }
  return hash;
};
// Для примера:
console.log("Answer42".hashCode()); // Вернёт: 7291972

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

Использование BigInt и Math.imul

С помощью BigInt и Math.imul, можно получить хеш, диапазон значений которого гораздо шире:

JS
Скопировать код
function bigIntHash(str, seed = 0) {
  const prime = 31n;
  let hash = BigInt(seed);
  for (let i = 0; i < str.length; i++) {
    const charCode = BigInt(str.charCodeAt(i));
    hash = hash * prime + charCode;
  }
  return hash.toString();
}
// Пример использования:
console.log(bigIntHash("YourNameHere")); // Вернёт огромное число

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

Применение хеш-функции FNV-1a

Хеш-функция FNV-1a – это комбинация равномерного распределения значений и хорошей производительности:

JS
Скопировать код
function fnv1aHash(str) {
  const prime = 0x811C9DC5;
  let hash = prime;
  for (let i = 0; i < str.length; i++) {
    hash ^= str.charCodeAt(i);
    hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
  }
  return hash >>> 0;
}
// Посмотрим на примере:
console.log(fnv1aHash("NowIsTheTime")); // Результат можно увидеть в консоли!

Мастерство хеширования: меньше значит больше

Выбор наилучшего метода хеширования требует внимательной оценки:

  • Преобразование символов в значения ASCII упрощает работу большинства алгоритмов хеширования.
  • Используя функцию reduce, можно элегантно вычислить хеш из массива или строки.
  • Управление массивами: Стоит стремиться обрабатывать байтовые массивы как можно дольше до их преобразования в шестнадцатеричные строки. Это помогает снизить накладные расходы (overhead).

Так применяется функция reduce в JavaScript:

JS
Скопировать код
function reducedHash(str) {
  return str.split("").reduce((acc, char) => {
    return ((acc << 5) – acc) + char.charCodeAt(0);
  }, 0);
}
// Посмотрим на пример:
console.log(reducedHash("reducedHash")); // Результат интересен!

Рассуждения по оптимизированному хешированию

Выполняя создание функции хеширования в JavaScript, учитывайте следующие особенности:

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

Визуализация

Процесс генерации хеша строки можно уподобить процессу готовки блюда:

Markdown
Скопировать код
Оригинальный рецепт (📄): "Hello World"

Добавляем специи (выбранную нами хеш-функцию):

Markdown
Скопировать код
📄 + 🌿 (Добавляем функцию хеширования) -> 🥣 (Проводим смешивание)

Получаем готовое блюдо (конечный хеш):

Markdown
Скопировать код
🥣 Превращаем в 🍲: "5eb63bbbe01eeed093cb22bb8f5acdc3"

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

Использование хешей с учетом безопасности

  • Ограничения на клиентской стороне: Используя хещирование на клиентской стороне, не забывайте о безопасности. Для конфиденциальных данных серверная генерация хешей всегда будет предпочтительнее.
  • Необратимость: Важно использовать необратимые алгоритмы для обеспечения надёжности хеширования.
  • Независимость от серверной стороны: Клиентская генерация хешей обладает своими преимуществами и сложностями. Важно не забывать о мер безопасности и правильном использовании этого подхода.