Avatar ·

Как создать GUID / UUID в JavaScript? Нужен рабочий метод

Всем привет! Я пишу небольшое веб-приложение на чистом JavaScript (без фреймворков), и мне нужно генерировать уникальные идентификаторы для записей в локальном хранилище (localStorage). Проблема в том, что пользователи могут создавать много записей, и я хочу избежать коллизий (совпадения ID). Я знаю, что в других языках (например, в C# или Python) есть встроенные функции для создания GUID/UUID. В JavaScript я такого не нашел. Пробовал писать свою функцию через Math.random(), но, почитав на Stack Overflow, понял, что это небезопасно и может давать дубликаты. Вот что я пробовал: ```javascript function generateId() { return Math.random().toString(36).substr(2, 9); } ``` Это работает, но я не уверен в уникальности. Видел, что многие рекомендуют использовать API `crypto.randomUUID()`, но не знаю, поддерживается ли он во всех браузерах. Еще есть вариант с библиотеками (например, uuid), но я хотел бы обойтись без внешних зависимостей. Подскажите, пожалуйста, как правильно и надежно генерировать UUID (желательно версии 4) на чистом JavaScript? Какие есть современные стандартные методы? Нужно ли учитывать поддержку старых браузеров? Буду благодарен за примеры кода с пояснениями. <<>>

Современное решение: crypto.randomUUID()

Начиная с 2022 года, в JavaScript появился встроенный метод crypto.randomUUID(), который генерирует UUID версии 4 (случайный). Это самый простой и безопасный способ. Он доступен во всех современных браузерах (Chrome, Firefox, Safari, Edge) и в Node.js 19+. Метод использует криптостойкий генератор случайных чисел, что гарантирует уникальность.

// Самый простой способ
const uuid = crypto.randomUUID();
console.log(uuid); // Пример: "550e8400-e29b-41d4-a716-446655440000"

Поддержка браузерами (по состоянию на 2024 год):

  • Chrome 92+
  • Firefox 95+
  • Safari 15.4+
  • Edge 92+
  • Opera 78+

Универсальное решение для старых браузеров

Если вам нужно поддерживать старые браузеры (например, Internet Explorer), используйте crypto.getRandomValues(). Этот метод доступен с IE 11 и во всех современных браузерах. Вот надежная функция, которая генерирует UUID v4:

function generateUUID() {
  // Создаем 16 случайных байт (128 бит)
  const bytes = new Uint8Array(16);
  crypto.getRandomValues(bytes);

  // Настраиваем биты для UUID v4
  bytes[6] = (bytes[6] & 0x0f) | 0x40; // Версия 4
  bytes[8] = (bytes[8] & 0x3f) | 0x80; // Вариант RFC 4122

  // Преобразуем байты в строку UUID
  const hex = Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('');
  return `${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20)}`;
}

// Использование
console.log(generateUUID()); // "f47ac10b-58cc-4372-a567-0e02b2c3d479"

Почему не стоит использовать Math.random()?

Метод Math.random() не является криптостойким — он предсказуем и может давать коллизии при большом количестве генераций. Для уникальных идентификаторов всегда используйте crypto API.

Как проверить поддержку?

Можно написать функцию, которая автоматически выбирает подходящий метод:

function createUUID() {
  // Современный метод
  if (typeof crypto.randomUUID === 'function') {
    return crypto.randomUUID();
  }
  // Fallback для старых браузеров
  const bytes = new Uint8Array(16);
  crypto.getRandomValues(bytes);
  bytes[6] = (bytes[6] & 0x0f) | 0x40;
  bytes[8] = (bytes[8] & 0x3f) | 0x80;
  const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');
  return `${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20)}`;
}

Этот код будет работать везде: от IE 11 до последних версий браузеров. Для вашего случая с localStorage я рекомендую использовать именно crypto.randomUUID() — он быстрый, надежный и не требует внешних библиотек.

<<>>

Альтернативный подход: библиотека uuid и использование в Node.js

Если вы работаете в среде Node.js (серверная часть) или используете сборщик (Webpack, Vite), рекомендую установить пакет uuid — это отраслевой стандарт для генерации UUID в JavaScript:

npm install uuid

Пример использования:

import { v4 as uuidv4 } from 'uuid';
// или для CommonJS:
// const { v4: uuidv4 } = require('uuid');

const myId = uuidv4();
console.log(myId); // "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed"

Преимущества библиотеки:

  • Поддержка UUID версий 1, 3, 4, 5
  • Криптостойкая генерация на всех платформах
  • Автоматический выбор лучшего доступного метода (crypto.randomUUID или fallback)
  • Большое сообщество и регулярные обновления

Для браузеров без сборщика можно подключить CDN-версию:

<script src="https://cdn.jsdelivr.net/npm/uuid@9/dist/umd/uuid.min.js"></script>
<script>
  const id = uuid.v4();
  console.log(id);
</script>

Этот подход особенно удобен, если вы уже используете npm-пакеты в проекте. Библиотека uuid — это "золотой стандарт", который используют миллионы проектов по всему миру.