Как создать GUID / UUID в JavaScript?
Стандартное решение: метод crypto.randomUUID()
Начиная с 2022 года, в современном JavaScript появился встроенный метод для генерации UUID версии 4 (случайный UUID). Он доступен через глобальный объект crypto, который есть во всех современных браузерах и Node.js 19+. Это самый правильный и безопасный способ.
const uuid = crypto.randomUUID();
console.log(uuid); // Пример: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
Как это работает?
Метод crypto.randomUUID() генерирует UUID версии 4 (RFC 4122). Он использует криптостойкий генератор случайных чисел (crypto.getRandomValues()), что гарантирует:
- Уникальность — вероятность коллизии ничтожно мала (около 5.3 × 10⁻³⁶ для 122 бит случайных данных).
- Безопасность — невосприимчив к атакам, основанным на предсказании случайных чисел.
- Стандартный формат — возвращает строку вида
xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx, где4— версия UUID, аy— вариант (8, 9, a или b).
Формат UUID v4
UUID состоит из 32 шестнадцатеричных цифр, разделённых дефисами на 5 групп: 8-4-4-4-12. В версии 4:
- 13-й символ всегда
4(указывает версию). - 17-й символ — один из
8, 9, a, b(указывает вариант). - Остальные 122 бита — случайные.
Полифилл для старых браузеров / Node.js
Если нужно поддерживать старые окружения, можно использовать crypto.getRandomValues() напрямую:
function generateUUID() {
const chars = '0123456789abcdef';
const randomValues = new Uint8Array(16);
crypto.getRandomValues(randomValues);
// Устанавливаем версию (4) и вариант (8, 9, a, b)
randomValues[6] = (randomValues[6] & 0x0f) | 0x40; // Версия 4
randomValues[8] = (randomValues[8] & 0x3f) | 0x80; // Вариант
let uuid = '';
for (let i = 0; i < 16; i++) {
if (i === 4 || i === 6 || i === 8 || i === 10) {
uuid += '-';
}
uuid += chars[randomValues[i] >> 4] + chars[randomValues[i] & 0x0f];
}
return uuid;
}
console.log(generateUUID()); // "f47ac10b-58cc-4372-a567-0e02b2c3d479"
Почему не стоит использовать Math.random()?
Хотя Math.random() даёт псевдослучайные числа, он:
- Не является криптостойким — его можно предсказать.
- Имеет ограниченную энтропию (около 52 бит против 122 бит в UUID v4).
- Может давать коллизии при большом количестве генераций (парадокс дней рождения).
Использование в Node.js
В Node.js 19+ метод доступен напрямую. Для более старых версий используйте модуль uuid:
npm install uuid
const { v4: uuidv4 } = require('uuid');
console.log(uuidv4()); // "f47ac10b-58cc-4372-a567-0e02b2c3d479"
Когда использовать UUID?
- Базы данных — как первичный ключ (особенно в распределённых системах).
- Клиент-серверное взаимодействие — для идентификации запросов/сессий.
- Локальное хранилище — для уникальных ID объектов (задачи, заметки).
- URL-идентификаторы — если нужно скрыть порядковый номер (например,
/user/f47ac10b-58cc-4372-a567-0e02b2c3d479).
Вывод: Используйте crypto.randomUUID() — это современный, безопасный и стандартизированный способ. Если нужна поддержка старых браузеров — используйте полифилл на основе crypto.getRandomValues().
Альтернативный подход: библиотека nanoid
Если вам не нужна полная совместимость со стандартом UUID, а требуется просто компактный и быстрый уникальный идентификатор, обратите внимание на библиотеку nanoid. Она генерирует более короткие ID (по умолчанию 21 символ), но с той же степенью уникальности.
// Установка: npm install nanoid
import { nanoid } from 'nanoid';
const id = nanoid(); // "V1StGXR8_Z5jdHi6B-myT"
console.log(id); // 21 символ
Преимущества nanoid
- Компактность — ID короче UUID (21 символ против 36).
- Скорость — в 2-3 раза быстрее генерации UUID.
- Настраиваемость — можно изменить длину и алфавит.
- Безопасность — использует
crypto.getRandomValues().
// Свой алфавит и длина
const customNanoid = nanoid.customAlphabet('1234567890abcdef', 10);
console.log(customNanoid()); // "a3f8b2c1d0"
Когда выбирать nanoid вместо UUID?
- Нужны короткие URL или читаемые ID.
- Не требуется строгое соответствие стандарту UUID.
- Важна производительность (например, в циклах с тысячами генераций).
Однако помните: если ваша система должна взаимодействовать с другими системами, ожидающими формат UUID, лучше использовать crypto.randomUUID().