Что такое ULID и чем он отличается от UUID
ULID (Universally Unique Lexicographically Sortable Identifier) — это формат идентификатора, который решает сразу несколько проблем, присущих классическому UUID v4. На этой странице вы можете сгенерировать от 1 до 100 ULID за один клик, выбрав соответствующий пункт в выпадающем списке форматов. В отличие от UUID, ULID занимает 26 символов вместо 36, не содержит дефисов и использует только алфавит Крокфорда base32 (цифры 0–9 и буквы A–Z с исключением I, L, O, U). Это делает строки регистронезависимыми — вы можете вводить их в верхнем или нижнем регистре, и они будут считаться одинаковыми.
Главное же отличие — временная сортируемость. Первые 10 символов ULID кодируют временную метку с точностью до миллисекунды. Если отсортировать сгенерированные идентификаторы в лексикографическом порядке (как строки), они расположатся в том же порядке, в котором были созданы. Это свойство особенно ценно, когда нужно упорядочить записи без отдельного столбца времени.
Внутреннее устройство ULID: 128 бит, разбитые на две части
Под капотом ULID представляет собой 128-битное значение, которое делится строго пополам по смыслу, но не по длине в символах.
- Временная метка (48 бит) — занимает первые 10 символов. Она хранит количество миллисекунд, прошедших с 1 января 1970 года (Unix-эпоха). 48 бит позволяют закодировать время до 10895 года, что с большим запасом покрывает любые текущие задачи.
- Случайная часть (80 бит) — занимает оставшиеся 16 символов. Она состоит из случайной последовательности, которую генератор получает с помощью криптостойкого источника
crypto.getRandomValues()прямо в вашем браузере. Никакие данные не отправляются на сервер — всё происходит локально.
Алфавит Крокфорда base32 выбран не случайно. Он исключает символы, которые легко спутать визуально: I и L, O и 0, U и V. Это снижает риск ошибок при ручном вводе или передаче устно. Кроме того, все символы ULID являются допустимыми в URL без экранирования (согласно RFC 3986), поэтому идентификаторы можно смело использовать в адресной строке без процентного кодирования.
Сортировка и её ограничения: что значит «сортируемые по времени»
Поскольку метка времени занимает первые 10 символов, ULID ведут себя как естественный ключ для сортировки. Если вы сгенерировали 100 ID подряд, они будут располагаться в хронологическом порядке — более новые идут после старых. Это особенно важно в распределённых системах, где разные узлы могут создавать ID независимо: при слиянии данных вы получите приблизительную временную упорядоченность.
Однако важно понимать: ULID не гарантирует строгий порядок в пределах одной миллисекунды. Если 100 ID сгенерированы в один и тот же миллисекундный интервал, их порядок будет определяться случайной частью. В такой ситуации лексикографическая сортировка покажет ID в случайном порядке относительно друг друга. Для абсолютной упорядоченности внутри миллисекунды нужны другие методы (например, последовательный счётчик), но ULID для этого не предназначен.
Тем не менее для большинства практических задач — первичные ключи в таблицах, идентификация событий в логах, генерация ссылок — этого достаточно. В базах данных с B-деревьями (например, PostgreSQL или MySQL) новые ULID чаще всего вставляются в правую часть индекса, что уменьшает фрагментацию и ускоряет запись по сравнению со случайными UUID.
Как работает генератор на этой странице
На странице «ULID Generator» управление минимально. Вы выбираете формат «ULID» (он может быть предустановлен) и задаёте количество идентификаторов — целое число от 1 до 100 включительно. После нажатия кнопки (или автоматически, если вы изменили параметры) генерируется список.
Что вы видите на выходе:
- Список ULID, каждый длиной ровно 26 символов. Никаких дефисов, никаких заглавных/строчных «переключателей» — формат не предполагает таких опций, потому что регистр не имеет значения.
- Счётчик сгенерированных ID (например, «Сгенерировано 50»).
- Индикатор состояния: «Готово.», «Сгенерировано.», а после копирования всего списка — «Скопировано всё!».
Как копировать:
- Клик по отдельному ULID копирует его в буфер обмена.
- Кнопка копирования всего списка копирует все строки сразу.
Важный нюанс: любое изменение входных данных (смена формата, изменение количества) приводит к полной перегенерации списка. Нельзя «добавить» новые ID к уже существующим — только заново. Это сделано для предсказуемости и согласованности.
Все ID создаются исключительно в вашем браузере с использованием криптостойкого генератора случайных чисел crypto.getRandomValues(). Никакой запрос на сервер не отправляется. Это значит, что приватность гарантирована — вы можете генерировать сколь угодно много ID, не опасаясь утечки.
Кому нужны ULID: практические сценарии
- Веб- и мобильные разработчики — для формирования коротких, но читаемых идентификаторов в URL. ULID на 10 символов короче UUID, не содержит дефисов, не чувствителен к регистру — это упрощает копирование и снижает количество опечаток.
- Администраторы баз данных — при проектировании первичных ключей для InnoDB или других B-деревьев. Монотонно возрастающие ключи уменьшают количество страничных разделений и ускоряют INSERT.
- Архитекторы распределённых систем — когда узлы генерируют идентификаторы независимо, а потом их нужно слить. Сортировка по ULID даёт хотя бы приблизительную хронологию, что упрощает отладку и анализ.
- Проектировщики публичных API — чтобы выдавать клиентам идентификаторы, которые трудно угадать (80 бит случайности), но легко передавать в GET-параметрах без экранирования.
Для сравнения: NanoID может быть короче (21 символ), но не гарантирует временной сортировки. UUID v7 (черновик) тоже добавляет метку времени, но остаётся 36 символов с дефисами. ULID предлагает компромисс: компактность, сортируемость и полная 128-битная энтропия.
Часто задаваемые вопросы
1. Какова вероятность коллизии у ULID? Случайная часть — 80 бит. Если генерировать 1 миллион ID в секунду, потребуется несколько лет, чтобы вероятность коллизии стала значимой. На практике для любых разумных нагрузок уникальность обеспечена.
2. Почему ULID регистронезависим? Потому что он использует алфавит Крокфорда base32. Символы «A» и «a» соответствуют одному и тому же пятибитному значению. Вы можете написать ULID прописными или строчными — это не влияет на значение.
3. Можно ли получить UUID из ULID или наоборот? Форматы разные. ULID — это способ кодирования 128 бит в 26 символов base32, а UUID (в стандартном представлении) — 36 символов hex с дефисами. Они не эквивалентны. Если вам нужно преобразовать ULID в UUID, придётся перекодировать двоичное представление.
4. Почему на этой странице нет опции «с дефисами» или «верхний регистр»? Потому что в ULID дефисы не предусмотрены спецификацией — они только нарушили бы фиксированную длину и сортируемость. Регистр также не имеет значения: все символы можно читать как в верхнем, так и в нижнем регистре. Поэтому переключатели излишни.
5. Что произойдёт, если ввести 0 или 101 в поле количества? Интерфейс не примет значения вне диапазона 1–100. Если попытаться ввести недопустимое число, генерация не запустится. Счётчик всегда целый, без десятичных дробей.
6. ULID — это стандарт? Да, он описан в RFC-стиле на GitHub-репозитории ulid/spec. Он не утверждён IETF, но широко используется в сообществе. Формат строго определён, и любая реализация должна давать одинаковый результат при одинаковой временной метке и случайности.