UUID v4 в JavaScript: crypto.randomUUID()

·TypeScript & Full-stack Developer·ПровереноMarcus Webb·Опубликовано

Используйте бесплатный UUID v4 Generator прямо в браузере — установка не требуется.

Попробовать UUID v4 Generator онлайн →

Каждому JavaScript-приложению рано или поздно нужны уникальные идентификаторы — токены сессий, строки баз данных, ключи идемпотентности для платёжных API, идентификаторы корреляции для распределённой трассировки. Самый простой способ сгенерировать UUID v4 в JavaScript сегодня — это crypto.randomUUID(): ноль зависимостей, одна строка, криптографически безопасен. UUID v4 широко используется именно потому, что не требует координации между сервисами — клиент и сервер могут генерировать ID независимо без риска коллизий. Это руководство охватывает встроенный API, uuid npm-пакет, валидацию — всё для Node.js 19+ и современных браузеров. Для варианта без кода, UUID v4 Generator на ToolDeck мгновенно создаёт корректные идентификаторы.

  • crypto.randomUUID() встроен в браузеры и Node.js — ноль зависимостей, одна строка кода.
  • UUID v4 — 128-битный случайный идентификатор: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx (y равен 8, 9, a или b).
  • Валидируйте через /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i — проверяет версию и биты варианта.
  • npm-пакет uuid добавляет поддержку v1, v3, v5 и v7, когда нужно больше, чем случайные ID.
  • Для первичных ключей баз данных предпочтите UUID v7 (упорядоченный по времени) вместо v4 (случайного), чтобы снизить фрагментацию индекса.

Что такое UUID v4?

UUID (Universally Unique Identifier) версии 4 — это 128-битный случайный идентификатор, отформатированный как 32 шестнадцатеричных цифры, разделённых четырьмя дефисами: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx. 4 на позиции 15 обозначает версию. Символ y на позиции 20 — одно из 8, 9, a или b (вариант RFC 4122). Оставшиеся 122 бита случайны. UUID v4 является наиболее распространённой версией в JavaScript-приложениях, поскольку не требует координации между системами — ID можно генерировать независимо на клиенте и сервере без беспокойства о коллизиях.

Before · javascript
After · javascript
// Без идентификатора
const event = { action: "user.login", ts: 1711824000 };
// С UUID v4
const event = {
  id: "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
  action: "user.login",
  ts: 1711824000
};

crypto.randomUUID() — Нативный подход в JavaScript

crypto.randomUUID() доступен в Chrome 92+, Firefox 95+, Safari 15.4+ и Node.js 19+ (с экспериментальной поддержкой начиная с Node.js 14.17.0 через globalThis.crypto). Возвращает строку UUID v4 в нижнем регистре из 36 символов. В браузерном JavaScript импорт не требуется. В Node.js можно вызывать напрямую через глобальный объект cryptoили явно импортировать из модуля node:crypto.

JavaScript — браузер (без импортов)
// Работает в любом современном браузере — без этапа сборки, без бандлера
const requestId = crypto.randomUUID();
console.log(requestId);
// "3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f"

// Используйте везде, где нужен уникальный идентификатор
const telemetryEvent = {
  event_id: crypto.randomUUID(),
  action: "checkout.started",
  session_id: crypto.randomUUID(),
  timestamp: Date.now(),
  cart_total_cents: 14999,
};
console.log(JSON.stringify(telemetryEvent, null, 2));
Node.js — два равнозначных подхода
// Подход 1: глобальный crypto (Node.js 19+)
const orderId = crypto.randomUUID();
console.log(orderId);
// "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"

// Подход 2: явный импорт из node:crypto
import { randomUUID } from 'node:crypto';
const correlationId = randomUUID();
console.log(correlationId);
// "f7e6d5c4-b3a2-4190-8f7e-6d5c4b3a2190"

Проверка наличия crypto.randomUUID через feature detection стоит выполнить, если ваш код может работать в старых браузерах или встроенных WebView. Проверка сводится к одной guard-конструкции с typeof:

JavaScript — определение возможностей с запасным вариантом
function generateUUIDv4() {
  // Предпочитаем нативный API, если доступен
  if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
    return crypto.randomUUID();
  }

  // Ручной запасной вариант с использованием getRandomValues (см. следующий раздел)
  const bytes = new Uint8Array(16);
  crypto.getRandomValues(bytes);

  // Устанавливаем версию (4) и вариант (RFC 4122)
  bytes[6] = (bytes[6] & 0x0f) | 0x40; // версия 4
  bytes[8] = (bytes[8] & 0x3f) | 0x80; // вариант 10xx

  const hex = [...bytes].map(b => b.toString(16).padStart(2, '0'));
  return [
    hex.slice(0, 4).join(''),
    hex.slice(4, 6).join(''),
    hex.slice(6, 8).join(''),
    hex.slice(8, 10).join(''),
    hex.slice(10, 16).join(''),
  ].join('-');
}

console.log(generateUUIDv4());
// "9b2e4f1a-7c3d-4e8f-a5b6-0d2c1e9f8a7b"
Примечание:В защищённых контекстах (HTTPS-страницы, localhost, расширения браузера) crypto.randomUUID() всегда доступен. В некоторых браузерах он выбрасывает исключение на обычных HTTP-страницах. Если ваше приложение иногда работает на обычном HTTP в процессе разработки, описанный выше запасной вариант с getRandomValues обрабатывает этот случай.

Генерация UUID v4 без библиотеки

Иногда нельзя полагаться на crypto.randomUUID() — возможно, вы работаете с WebView, в котором отключён API crypto, или хотите понять, что происходит под капотом. Ручной подход использует crypto.getRandomValues() (доступен начиная с IE 11) для заполнения 16 байт случайными данными, затем применяет две операции битовой маски для установки полей версии и варианта. Эти две операции — единственное отличие UUID v4 от строки чисто случайных байт.

JavaScript — ручной UUID v4 с getRandomValues
function uuidv4Manual() {
  const bytes = new Uint8Array(16);
  crypto.getRandomValues(bytes);

  // Устанавливаем версию: биты 12–15 байта 6 = 0100 (версия 4)
  bytes[6] = (bytes[6] & 0x0f) | 0x40;

  // Устанавливаем вариант: биты 6–7 байта 8 = 10 (RFC 4122)
  bytes[8] = (bytes[8] & 0x3f) | 0x80;

  const hex = [...bytes].map(b => b.toString(16).padStart(2, '0'));

  return (
    hex.slice(0, 4).join('') + '-' +
    hex.slice(4, 6).join('') + '-' +
    hex.slice(6, 8).join('') + '-' +
    hex.slice(8, 10).join('') + '-' +
    hex.slice(10, 16).join('')
  );
}

const traceId = uuidv4Manual();
console.log(traceId);
// "e4d7c2a1-3f9b-48e5-a612-9d8c7b6a5f4e"

// Проверяем, что проходит валидацию UUID v4
const UUID_V4_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
console.log(UUID_V4_RE.test(traceId)); // true
Предупреждение:Никогда не используйте Math.random() для генерации UUID. Он не является криптографически безопасным, его период вывода слишком короток, а некоторые движки генерируют предсказуемые последовательности. Всегда используйте crypto.getRandomValues() или crypto.randomUUID().

npm-пакет uuid — поддержка нескольких версий

Пакет uuid на npm был основной UUID-библиотекой для JavaScript ещё до появления crypto.randomUUID(). Он по-прежнему имеет смысл в трёх ситуациях: вам нужны версии UUID, отличные от v4 (v1, v3, v5, v7), вы работаете с окружениями старше Node.js 14.17.0, или вам нужны вспомогательные функции validate и parse. Для простой генерации UUID v4 в современном окружении нативного API вполне достаточно, и я бы не стал добавлять эту зависимость.

bash — установка
npm install uuid
JavaScript — пакет uuid для генерации v4
import { v4 as uuidv4, validate, version } from 'uuid';

// Генерация UUID v4
const paymentId = uuidv4();
console.log(paymentId);
// "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed"

// Валидация любой строки UUID
console.log(validate(paymentId));    // true
console.log(validate("not-a-uuid")); // false

// Определение версии UUID
console.log(version(paymentId));     // 4

// Генерация пакета для заполнения тестовой базы данных
const testAccounts = Array.from({ length: 5 }, () => ({
  account_id: uuidv4(),
  plan: "starter",
  created_at: new Date().toISOString(),
}));
console.log(testAccounts);
Примечание:Пакет uuid внутренне использует crypto.getRandomValues() в браузерах и crypto.randomBytes() в Node.js, поэтому источник энтропии идентичен нативному API. Разница лишь в дополнительных вспомогательных функциях и поддержке нескольких версий.

Если вы предпочитаете не писать код вовсе, воспользуйтесь UUID v4 Generator — он генерирует соответствующие RFC 4122 идентификаторы v4 прямо в браузере одним нажатием.

Детерминированные UUID — генерация UUID v5 из строки

UUID v4 по определению случаен — два последовательных вызова всегда дают разные результаты. Иногда нужна противоположность: одна и та же входная строка всегда должна давать один и тот же UUID. Именно это делает UUID v5. Он хеширует пространство имён UUID и входную строку с помощью SHA-1, затем форматирует результат как UUID. Одинаковое пространство имён + одинаковый ввод = одинаковый вывод, всегда, на любой машине. Это полезно для получения стабильных ID из URL, адресов электронной почты или любых строк, которые уже идентифицируют ресурс.

JavaScript — uuid v5 для детерминированных ID
import { v5 as uuidv5 } from 'uuid';

// Встроенное пространство имён для URL (RFC 4122)
const URL_NAMESPACE = uuidv5.URL;
// "6ba7b811-9dad-11d1-80b4-00c04fd430c8"

// Один и тот же URL всегда даёт один и тот же UUID
const pageId1 = uuidv5("https://api.warehouse.dev/products/sku-7291", URL_NAMESPACE);
const pageId2 = uuidv5("https://api.warehouse.dev/products/sku-7291", URL_NAMESPACE);
console.log(pageId1 === pageId2); // true
console.log(pageId1);
// "a6e4e1c0-7e23-5d3b-8f14-9c2a1b3d5e7f"

// Пользовательское пространство имён для вашего приложения
const APP_NAMESPACE = "f47ac10b-58cc-4372-a567-0e02b2c3d479";
const tenantId = uuidv5("acme-corp", APP_NAMESPACE);
console.log(tenantId);
// "d4735e3a-265b-564e-8f32-7a1b2c3d4e5f"

Небольшое замечание: UUID v3 делает то же самое, но использует MD5 вместо SHA-1. Для новых проектов предпочтите v5. У MD5 есть известные уязвимости к коллизиям, и хотя для генерации ID это не имеет большого значения, нет смысла выбирать его вместо SHA-1, когда оба доступны.

Справочник по crypto.randomUUID() и связанным API

Нативная функция crypto.randomUUID() не принимает аргументов — она возвращает строку и ничего более. Используйте её, когда нужны RFC 4122-совместимые идентификаторы без зависимостей. Когда вместо форматированной строки UUID нужны сырые случайные байты — например, для заполнения типизированного массива или получения ключа — обращайтесь напрямую к crypto.getRandomValues(). Связанные API, важные для работы с UUID, перечислены ниже.

Свойство / Метод
Тип возвращаемого значения
Описание
crypto.randomUUID()
string
Возвращает 36-символьную строку UUID v4 в нижнем регистре с шестнадцатеричными цифрами и дефисами
crypto.getRandomValues(arr)
TypedArray
Заполняет типизированный массив криптографически случайными значениями — основа для ручной генерации UUID
URL.createObjectURL(blob)
string
Генерирует уникальный blob URL (не UUID, но иногда с ним путают)

Разбор шаблона регулярного выражения UUID v4:

Сегмент
Шаблон
Значение
[0-9a-f]{8}
xxxxxxxx
Первые 8 шестнадцатеричных цифр — 32 случайных бита
[0-9a-f]{4}
xxxx
Следующие 4 шестнадцатеричных цифры — 16 случайных битов
4[0-9a-f]{3}
4xxx
Nibble версии фиксирован на 4, затем 12 случайных битов
[89ab][0-9a-f]{3}
yxxx
Nibble варианта — одно из 8, 9, a, b — затем 12 случайных битов
[0-9a-f]{12}
xxxxxxxxxxxx
Последние 12 шестнадцатеричных цифр — 48 случайных битов

Валидация UUID v4 с помощью регулярного выражения

Проверка того, что строка является корректным UUID v4, встречается постоянно — тела входящих API-запросов, параметры URL, полезные нагрузки вебхуков. Ручное регулярное выражение — правильный выбор, когда нужно ноль зависимостей и валидация только v4. Если вы уже используете пакет uuid, предпочтите его экспорт validate() — он обрабатывает все версии UUID и менее подвержен ошибкам, чем поддержка пользовательского шаблона. Регулярное выражение /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i проверяет как nibble версии (должен быть 4), так и nibble варианта (должен быть 8, 9, a или b). Используйте RegExp.prototype.test() для булевых проверок и .match() когда нужно извлечь UUID из окружающего текста.

JavaScript — вспомогательная функция валидации UUID v4
const UUID_V4_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;

function isUUIDv4(str) {
  return UUID_V4_RE.test(str);
}

// Корректный UUID v4
console.log(isUUIDv4("9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d")); // true

// UUID v1 — nibble версии равен 1, а не 4
console.log(isUUIDv4("550e8400-e29b-11d4-a716-446655440000")); // false

// UUID v7 — nibble версии равен 7
console.log(isUUIDv4("018e4a0c-5b3f-7d12-8a9b-0c1d2e3f4a5b")); // false

// Некорректные строки
console.log(isUUIDv4("not-a-uuid"));           // false
console.log(isUUIDv4(""));                      // false
console.log(isUUIDv4("9b1deb4d3b7d4bad9bdd2b0d7b3dcb6d")); // false (нет дефисов)

// Извлечение UUID из более длинной строки
const logLine = 'Request req_id=9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d failed with 503';
const match = logLine.match(/[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i);
console.log(match?.[0]);
// "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"

Генерация и присвоение UUID из файла и ответа API

На практике crypto.randomUUID() редко вызывается изолированно. Постоянно встречаются два шаблона: присвоение ID записям перед их записью в базу данных и добавление идентификаторов корреляции к исходящим API-запросам, чтобы можно было отследить запрос по сервисам в логах.

Чтение файла NDJSON → Присвоение UUID → Запись обратно

Node.js — присвоение UUID записям из файла
import { readFileSync, writeFileSync } from 'node:fs';
import { randomUUID } from 'node:crypto';

function assignIds(inputPath, outputPath) {
  const lines = readFileSync(inputPath, 'utf-8')
    .split('\n')
    .filter(line => line.trim());

  const records = lines.map(line => {
    try {
      const record = JSON.parse(line);
      if (!record.id) {
        record.id = randomUUID();
      }
      return JSON.stringify(record);
    } catch (err) {
      console.error(`Skipping malformed line: ${err.message}`);
      return null;
    }
  }).filter(Boolean);

  writeFileSync(outputPath, records.join('\n') + '\n');
  console.log(`Assigned IDs to ${records.length} records → ${outputPath}`);
}

assignIds('warehouse-products.ndjson', 'warehouse-products-with-ids.ndjson');
// Assigned IDs to 1284 records → warehouse-products-with-ids.ndjson

Добавление идентификатора корреляции к исходящему API-запросу

Node.js — идентификатор корреляции для распределённой трассировки
import { randomUUID } from 'node:crypto';

async function createShipment(orderPayload) {
  const correlationId = randomUUID();

  try {
    const response = await fetch('https://api.logistics.dev/v2/shipments', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Correlation-ID': correlationId,
        'X-Idempotency-Key': randomUUID(),
      },
      body: JSON.stringify(orderPayload),
    });

    if (!response.ok) {
      const errorBody = await response.text();
      throw new Error(`Shipment API returned ${response.status}: ${errorBody}`);
    }

    const result = await response.json();
    console.log(`Shipment created: ${result.shipment_id} (correlation: ${correlationId})`);
    return result;
  } catch (err) {
    console.error(`[correlation:${correlationId}] Shipment failed: ${err.message}`);
    throw err;
  }
}

await createShipment({
  order_id: "ord_8a3f91bc",
  destination: { city: "Москва", state: "МСК", zip: "101000" },
  items: [{ sku: "WH-7291", quantity: 2, weight_kg: 1.4 }],
});

Генерация UUID из командной строки

Скрипт не всегда нужен. Node.js может сгенерировать UUID прямо из командной строки, что удобно для shell-скриптов, CI-пайплайнов и быстрого ad-hoc-тестирования. Флаг -e вычисляет одно выражение.

bash — генерация UUID из командной строки
# Один UUID
node -e "console.log(crypto.randomUUID())"
# 3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f

# Пять UUID сразу
node -e "for(let i=0;i<5;i++) console.log(crypto.randomUUID())"

# Генерация и присвоение переменной оболочки
export REQUEST_ID=$(node -e "process.stdout.write(crypto.randomUUID())")
echo "Request ID: $REQUEST_ID"

# Использование npx uuid (если пакет установлен глобально или нужен одноразовый запуск)
npx uuid v4
# 1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed
bash — генерация UUID в консоли браузера (без Node.js)
# Откройте DevTools любого браузера и введите:
crypto.randomUUID()
# "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"
Примечание:Если в CI-пайплайне нет Node.js, uuidgen предустановлен в macOS и большинстве дистрибутивов Linux. В современных системах он по умолчанию генерирует UUID v4.

Высокопроизводительная альтернатива — nanoid

Если вы генерируете тысячи ID в секунду и 36-символьный формат UUID не является жёстким требованием, рассмотрите nanoid. Он в 2 раза быстрее uuid.v4(), по умолчанию генерирует 21-символьный URL-безопасный ID и весит около 1 КБ после минификации. Результат не является UUID — это ID на пользовательском алфавите — поэтому не используйте его там, где требуется соответствие RFC 4122 (UUID-столбцы баз данных, API, проверяющие формат UUID, trace ID в OpenTelemetry). Но для внутренних идентификаторов корреляции, ключей компонентов React и URL-слагов он подходит отлично.

bash — установка nanoid
npm install nanoid
JavaScript — nanoid для коротких уникальных ID
import { nanoid, customAlphabet } from 'nanoid';

// По умолчанию: 21-символьный URL-безопасный ID (A-Za-z0-9_-)
const trackingCode = nanoid();
console.log(trackingCode);
// "V1StGXR8_Z5jdHi6B-myT"

// Пользовательская длина
const shortCode = nanoid(10);
console.log(shortCode);
// "IRFa-VaY2b"

// Пользовательский алфавит — только цифры, 12 символов
const numericId = customAlphabet('0123456789', 12);
console.log(numericId());
// "839274651023"

// Пользовательский алфавит — только hex, 32 символа (та же энтропия, что у UUID v4 без дефисов)
const hexId = customAlphabet('0123456789abcdef', 32);
console.log(hexId());
// "4f8a1b2c3d7e9f0a5b6c8d1e2f3a4b5c"

Вывод в терминале с подсветкой синтаксиса

Отладка приложений с большим количеством UUID означает просмотр стен из шестнадцатеричных строк в терминале. Цветовое кодирование помогает. Библиотека chalk (или более новый встроенный node:util styleText в Node.js 21.7+) позволяет выделять UUID в выводе логов, чтобы они выделялись на фоне окружающего текста.

Node.js — цветной вывод UUID с помощью chalk
import chalk from 'chalk';
import { randomUUID } from 'node:crypto';

function logEvent(action, metadata = {}) {
  const eventId = randomUUID();
  const timestamp = new Date().toISOString();

  console.log(
    chalk.gray(timestamp),
    chalk.cyan(eventId),
    chalk.white(action),
    Object.keys(metadata).length
      ? chalk.dim(JSON.stringify(metadata))
      : ''
  );
}

logEvent('shipment.created', { order_id: 'ord_8a3f', carrier: 'fedex' });
logEvent('payment.captured', { amount_cents: 14999, currency: 'USD' });
logEvent('webhook.delivered', { endpoint: 'https://hooks.acme.dev/orders' });
// 2026-03-27T10:15:00.000Z  a1b2c3d4-...  shipment.created  {"order_id":"ord_8a3f",...}
Предупреждение:Управляющие коды цвета портят лог-файлы и ломают JSON-парсеры. Используйте chalk или styleText только для вывода в терминал, который человек читает напрямую. Для структурированных логов, отправляемых в файл или агрегатор логов, используйте чистый JSON.

Генерация коротких уникальных ID в JavaScript

36-символьный UUID иногда слишком длинный — URL-слаги, данные QR-кодов, SMS-сообщения и встроенные аппаратные протоколы имеют ограничения по длине.

JavaScript — три техники для более коротких ID
import { randomUUID } from 'node:crypto';

// 1. Убираем дефисы из UUID v4 → 32-символьная hex-строка
const hex32 = randomUUID().replaceAll('-', '');
console.log(hex32);
// "3e7f1a924b0c4d8e9f127a6b3c8d5e1f" (32 символа)

// 2. Base64-кодируем 16 случайных байт → 22-символьная строка (URL-безопасная)
const bytes = new Uint8Array(16);
crypto.getRandomValues(bytes);
const base64Id = Buffer.from(bytes)
  .toString('base64url')
  .replace(/=+$/, '');
console.log(base64Id);
// "Pj8akksNTY6fEnarPIvR" (22 символа, 128 бит энтропии)

// 3. nanoid с пользовательской длиной
import { nanoid } from 'nanoid';
const short12 = nanoid(12);
console.log(short12);
// "V1StGXR8_Z5j" (12 символов, ~71 бит энтропии)

Математика вероятности коллизий: 12-символьный nanoid (алфавит по умолчанию из 64 символов) даёт примерно 71 бит энтропии. При генерации 1000 ID в секунду потребуется около 116 лет, чтобы достичь 1% вероятности коллизии. Для большинства приложений этого более чем достаточно. Если вы генерируете миллионы ID в день, используйте полный UUID или nanoid с не менее чем 21 символом.

UUID v7 — упорядоченная по времени альтернатива v4

UUID v7 (определён в RFC 9562) встраивает 48-битную временну́ю метку Unix в миллисекундах в первый сегмент, за которым следуют случайные биты. Результат — UUID, похожий на v4, но сортирующийся хронологически. Это делает его лучшим выбором по сравнению с v4 для первичных ключей баз данных: новые строки всегда попадают в конец B-tree-индекса, а не в случайные позиции, что снижает разделение страниц и фрагментацию. В проектах, где мне нужны упорядоченные по времени ID для таблицы Postgres, я немедленно перехожу на v7 — разница в производительности индекса ощутима в масштабе. UUID v7 Generator на ToolDeck показывает встроенную временну́ю метку для любого UUID v7.

JavaScript — UUID v7 с пакетом uuid
import { v7 as uuidv7 } from 'uuid';

// Генерируем три значения UUID v7 — обратите внимание, что они сортируются хронологически
const id1 = uuidv7();
const id2 = uuidv7();
const id3 = uuidv7();

console.log(id1);
// "018e4a0c-5b3f-7d12-8a9b-0c1d2e3f4a5b"
console.log(id2);
// "018e4a0c-5b40-7e34-9c2d-1e4f5a6b7c8d"
console.log(id3);
// "018e4a0c-5b41-7f56-ae3f-2a5b6c7d8e9f"

// Лексикографическая сортировка по времени создания
console.log([id3, id1, id2].sort());
// [id1, id2, id3] — сохраняется хронологический порядок

// Используйте v4 для токенов, где не должно быть информации о времени
import { v4 as uuidv4 } from 'uuid';
const sessionToken = uuidv4(); // полностью случайный, без информации о времени
Примечание:Пакет uuid поддерживает v7 начиная с версии 9.0.0. Если у вас более старая версия, выполните npm install uuid@latest для обновления.

UUID v4 в браузере без этапа сборки

Без бандлера, без npm, без транспилятора. Просто обычный HTML-файл. Это простейший способ сгенерировать UUID в клиентском JavaScript. Работает, потому что crypto.randomUUID() является встроенным браузерным API.

HTML — минимальный генератор UUID в браузере
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>UUID Generator</title></head>
<body>
  <p>Your UUID: <strong id="output"></strong></p>
  <button onclick="document.getElementById('output').textContent = crypto.randomUUID()">
    Generate
  </button>
  <script>
    // Генерируем один UUID при загрузке страницы
    document.getElementById('output').textContent = crypto.randomUUID();
  </script>
</body>
</html>

Это весь файл. Никаких импортов из CDN, никаких тегов script с библиотеками. Для чего-то более сложного — пакетной генерации, валидации, детерминированных ID — вам понадобится пакет uuid или ручной запасной вариант, показанный ранее. Но для быстрого прототипа или внутреннего инструмента этого достаточно.

Распространённые ошибки

Я видел шаблон UUID на основе Math.random() скопированным из старых блог-постов в продакшн-код чаще, чем хотелось бы признавать. Ошибки, которые привносят эти шаблоны, незаметны: никакой ошибки во время выполнения, только едва заметное неправильное поведение, которое проявляется позже под нагрузкой или в ходе проверки безопасности.

Использование Math.random() для генерации UUID

Проблема: Math.random() не является криптографически безопасным. Его вывод предсказуем в некоторых движках, а низкая энтропия делает коллизии гораздо более вероятными, чем при использовании настоящего ГПСЧ.

Решение: Всегда используйте crypto.randomUUID() или crypto.getRandomValues(). Оба используют ГПСЧ операционной системы.

Before · JavaScript
After · JavaScript
// НЕБЕЗОПАСНО — предсказуемо, низкая энтропия
function badUuid() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
    /[xy]/g,
    c => {
      const r = Math.random() * 16 | 0;
      return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    }
  );
}
// БЕЗОПАСНО — использует ГПСЧ ОС
const id = crypto.randomUUID();

// Или если нужен ручной запасной вариант:
function secureUuid() {
  const bytes = new Uint8Array(16);
  crypto.getRandomValues(bytes);
  bytes[6] = (bytes[6] & 0x0f) | 0x40;
  bytes[8] = (bytes[8] & 0x3f) | 0x80;
  const h = [...bytes].map(b => b.toString(16).padStart(2, '0'));
  return `${h.slice(0,4).join('')}-${h.slice(4,6).join('')}-${h.slice(6,8).join('')}-${h.slice(8,10).join('')}-${h.slice(10).join('')}`;
}
Сравнение UUID с чувствительным к регистру равенством

Проблема: crypto.randomUUID() возвращает шестнадцатеричные символы в нижнем регистре, но UUID из других систем (баз данных, API, пользовательского ввода) могут использовать верхний регистр. Прямое сравнение === даёт сбой при несовпадении регистра.

Решение: Нормализуйте обе стороны к нижнему регистру перед сравнением.

Before · JavaScript
After · JavaScript
const fromApi = "9B1DEB4D-3B7D-4BAD-9BDD-2B0D7B3DCB6D"; // верхний регистр из API
const local  = "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d";  // нижний регистр из crypto

if (fromApi === local) { /* никогда не выполнится */ }
const fromApi = "9B1DEB4D-3B7D-4BAD-9BDD-2B0D7B3DCB6D";
const local  = "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d";

if (fromApi.toLowerCase() === local.toLowerCase()) {
  // совпадение работает корректно
}
Хранение UUID как объектов вместо строк

Проблема: Некоторые UUID-библиотеки (особенно на других языках) возвращают объекты UUID. В JavaScript случайное оборачивание строки UUID в объект нарушает проверки равенства, JSON-сериализацию и запросы к базе данных.

Решение: Всегда храните и передавайте UUID как обычные строки. Если библиотека возвращает объект, сразу же вызовите .toString() или обратитесь к строковому свойству.

Before · JavaScript
After · JavaScript
// Создание ненужной обёртки
class UUID {
  constructor(value) { this.value = value; }
}
const id = new UUID(crypto.randomUUID());
console.log(id === id); // true, но...
console.log(JSON.stringify({ id })); // {"id":{"value":"..."}}
// Просто используйте строку
const id = crypto.randomUUID();
console.log(JSON.stringify({ id }));
// {"id":"3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f"}
Обращение с UUID v4 как с сортируемым

Проблема: UUID v4 полностью случаен. Сортировка по UUID v4 даёт произвольный порядок, а не порядок создания. Это приводит к непредсказуемой пагинации, неудобному пользовательскому интерфейсу администратора и плохой производительности индекса базы данных.

Решение: Используйте UUID v7, когда нужны упорядоченные по времени идентификаторы. Оставьте UUID v4 для токенов и идентификаторов корреляции, где порядок сортировки не важен.

Before · JavaScript
After · JavaScript
// Плохо: использование v4 как сортируемого первичного ключа
const rows = [
  { id: crypto.randomUUID(), created: "2026-03-27" },
  { id: crypto.randomUUID(), created: "2026-03-26" },
];
rows.sort((a, b) => a.id.localeCompare(b.id));
// Порядок сортировки случаен — НЕ по дате создания
import { v7 as uuidv7 } from 'uuid';
// Хорошо: v7 сортируется по времени создания
const rows = [
  { id: uuidv7(), created: "2026-03-27" },
  { id: uuidv7(), created: "2026-03-26" },
];
rows.sort((a, b) => a.id.localeCompare(b.id));
// Порядок сортировки соответствует времени создания

crypto.randomUUID() vs uuid vs nanoid — краткое сравнение

Метод
Формат вывода
Версии UUID
Размер бандла
Кастомные типы
Требует установки
crypto.randomUUID()
36-символьный UUID v4
Только v4
0 КБ
Нет
Нет (встроенный)
uuid npm package
36-символьный UUID
v1, v3, v4, v5, v6, v7
~6.5 КБ
Нет
npm install
nanoid
21-символьный URL-безопасный ID
Произвольный (не UUID)
~1 КБ
Нет
npm install
Manual getRandomValues
36-символьный UUID v4
Только v4
0 КБ
Нет
Нет (встроенный)
crypto.randomBytes (Node)
Buffer → 36-символьный UUID v4
Только v4
0 КБ
Нет
Нет (встроен в Node)
uuidv7 npm package
36-символьный UUID v7
Только v7
~2 КБ
Нет
npm install

Для большинства JavaScript-проектов: используйте crypto.randomUUID() когда нужен только UUID v4 и ваша среда выполнения достаточно современная. Обращайтесь к пакету uuid когда нужна поддержка v5 (детерминированных) или v7 (упорядоченных по времени). Используйте nanoid когда короткий URL-безопасный ID практичнее, чем 36-символьный UUID — но помните, что вывод nanoid не соответствует UUID и не пройдёт валидацию на любой системе, ожидающей формат RFC 4122.

Для варианта без кода попробуйте UUID v4 Generator для мгновенного создания идентификаторов в браузере. Чтобы проверить существующий UUID, вставьте его в UUID Decoder для просмотра его версии, варианта и любых встроенных данных временно́й метки.

Часто задаваемые вопросы

Как сгенерировать UUID v4 в JavaScript?

Вызовите crypto.randomUUID() в любом современном браузере (Chrome 92+, Firefox 95+, Safari 15.4+) или Node.js 19+. Функция возвращает строку в нижнем регистре вида "3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f". В браузере импорт не нужен — crypto является встроенным глобальным объектом; в Node.js можно явно указать import { randomUUID } from "node:crypto". Для версий Node.js старше 19 можно вызывать crypto.randomUUID() через глобальный объект — функция была доступна экспериментально начиная с Node.js 14.17.0. Если нужен вариант без кода, генератор UUID v4 на /en/uuid/v4 создаёт корректные идентификаторы в один клик.

JavaScript
const sessionId = crypto.randomUUID();
console.log(sessionId);
// "3e7f1a92-4b0c-4d8e-9f12-7a6b3c8d5e1f"

Является ли crypto.randomUUID() криптографически безопасным?

Да. crypto.randomUUID() использует тот же ГПСЧ (криптографически стойкий генератор псевдослучайных чисел), что и crypto.getRandomValues(). 122 случайных бита в UUID v4 делают вероятность коллизии пренебрежимо малой для любых практических целей — потребовалось бы сгенерировать примерно 2,71 квинтиллиона UUID, чтобы достичь 50% вероятности одной коллизии. Энтропия берётся из случайного источника операционной системы (/dev/urandom в Linux, BCryptGenRandom в Windows), а не из Math.random(), который явно не является криптографически безопасным. Это означает, что значения UUID v4 безопасно использовать в качестве токенов сессий, CSRF-токенов и других чувствительных с точки зрения безопасности идентификаторов, где предсказуемость должна быть исключена. Никогда не заменяйте генераторы UUID на основе Math.random() в контекстах безопасности.

Можно ли использовать UUID v4 в качестве первичного ключа базы данных?

Можно, но это влечёт заметный компромисс по производительности. UUID v4 полностью случаен, поэтому B-tree-индексы сильно фрагментируются: каждая новая строка вставляется в случайную позицию индекса, а не в конец. На таблицах с интенсивной записью это вызывает избыточное разделение страниц и промахи кэша, что ухудшает производительность INSERT и сканирования диапазонов. Если ваша база данных поддерживает это (PostgreSQL, MySQL 8.0+, SQL Server), UUID v7 с временным порядком является лучшим первичным ключом, поскольку новые строки всегда добавляются в конец индекса. UUID v4 остаётся правильным выбором для токенов сессий, параметров состояния OAuth, ключей идемпотентности, идентификаторов корреляции и любых полей, где желательно скрыть время создания.

JavaScript
// UUID v4 — случайный, не сортируемый
const correlationId = crypto.randomUUID();

// UUID v7 — упорядоченный по времени, лучше для первичных ключей БД
import { v7 as uuidv7 } from 'uuid';
const rowId = uuidv7();

В чём разница между UUID v4 и UUID v7?

UUID v4 заполняет 122 бита случайными данными — каждый сегмент фактически является шумом. UUID v7 (RFC 9562, опубликован в 2024) кодирует 48-битную временну́ю метку Unix в миллисекундах в первом сегменте, 12 бит субмиллисекундной точности во втором и случайные биты в остальной части. Оба имеют 128 бит и используют один и тот же 36-символьный формат с дефисами, поэтому они взаимозаменяемы на уровне хранения. UUID v7 лексикографически сортируется по времени создания, что сохраняет компактность B-tree-индексов и делает эффективными запросы диапазонов по временным окнам. Выбирайте UUID v4, когда ID не должен раскрывать время создания — например, публичные токены, где информация о времени может быть использована злоумышленником — и UUID v7 для первичных ключей баз данных, журналов аудита и потоков событий, где важен хронологический порядок.

Как проверить строку UUID v4 в JavaScript?

Проверьте по регулярному выражению /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i. Литерал "4" на позиции 15 (с нуля) подтверждает nibble версии; символ на позиции 20 — одно из 8, 9, a или b — кодирует биты варианта RFC 4122. Это регулярное выражение корректно отклоняет UUID v1, v7 и любую некорректную строку. Флаг i делает его нечувствительным к регистру, поэтому шестнадцатеричные цифры в верхнем регистре из других систем проходят проверку без нормализации. Если вам нужно только убедиться, что строка является допустимым UUID (независимо от версии), используйте более мягкий шаблон /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.

JavaScript
const UUID_V4_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;

UUID_V4_RE.test("550e8400-e29b-41d4-a716-446655440000"); // true
UUID_V4_RE.test("550e8400-e29b-11d4-a716-446655440000"); // false (v1)
UUID_V4_RE.test("not-a-uuid"); // false

Как сгенерировать короткий уникальный ID в JavaScript?

Удалите дефисы из UUID v4, чтобы получить 32-символьную шестнадцатеричную строку: crypto.randomUUID().replaceAll("-", ""). Для ещё более короткого варианта используйте nanoid, который по умолчанию создаёт 21-символьный URL-безопасный ID (A–Z, a–z, 0–9, _ и -) со сравнимой устойчивостью к коллизиям по сравнению с полным UUID. Компромисс прост: более короткие ID имеют большую вероятность коллизий, однако nanoid из 21 символа всё равно обеспечивает 126 бит энтропии, чего более чем достаточно практически для любого реального приложения. Для URL-слагов и данных QR-кодов можно использовать до 10–12 символов в nanoid, прежде чем вероятность коллизий станет проблемой при типичных темпах генерации. Не следует Base64-кодировать сырой UUID и обрезать его — обрезка нарушает статистическую независимость битов и усложняет рассуждения о коллизиях.

JavaScript
// 32-char hex string from UUID v4
const hexId = crypto.randomUUID().replaceAll('-', '');
// "3e7f1a924b0c4d8e9f127a6b3c8d5e1f"

// 21-char URL-safe ID via nanoid
import { nanoid } from 'nanoid';
const shortId = nanoid();
// "V1StGXR8_Z5jdHi6B-myT"

Связанные инструменты

Также доступно на:Python
SL
Sophie LaurentTypeScript & Full-stack Developer

Sophie is a full-stack developer focused on TypeScript across the entire stack — from React frontends to Express and Fastify backends. She has a particular interest in type-safe API design, runtime validation, and the patterns that make large JavaScript codebases stay manageable. She writes about TypeScript idioms, Node.js internals, and the ever-evolving JavaScript module ecosystem.

MW
Marcus WebbТехнический рецензент

Marcus specialises in JavaScript performance, build tooling, and the inner workings of the V8 engine. He has spent years profiling and optimising React applications, working on bundler configurations, and squeezing every millisecond out of critical rendering paths. He writes about Core Web Vitals, JavaScript memory management, and the tools developers reach for when performance really matters.