Русский

Инструменты разработчика · Генератор UUID

Символы от 128 Bits до 36: как работает кодировка текста UUID

· Как это работает

uuid криптография API-интерфейс браузера

128-битное значение отображается в виде байтов, затем в виде шестнадцатеричного 36-символа с дефисами, затем в виде 22-символьного base64url, иллюстрируя компромисс между пространством
Оригинальная векторная иллюстрация ToolAcre

UUID — это 16 bytes, однако его привычная форма состоит из 36 символов. В этом посте объясняется удвоение шестнадцатеричного кода, дефисы, правила регистра и более короткие кодировки, которые люди используют, когда стандартная форма слишком длинная.

Почему столбец шире значения — 16-байтовое значение, которое стоит 36 символов в тексте, и что это означает для URL-адресов и хранилища.

Ширина столбца хранилища увеличивается при выборе формата UUID. 128-битное значение — 16 bytes, но его текстовое представление зависит от кодировки: шестнадцатеричное (символы 36 с дефисами, 32 без), base64url (символы 22), base58 (символы 22–23), Crockford base32 (26 символов). Если ваша схема хранит UUID как VARCHAR(36), вы тратите 36 символов в каждой строке. В таблице с 1 миллиардов строк и отсутствием других столбцов это составляет 36 гигабайт текстовых издержек по сравнению с 16 гигабайтами двоичных данных. Выбор не просто косметический; это влияет на размер запроса, сетевые обращения и нагрузку на кэш. Канонический формат — 36 символов: восемь шестнадцатеричных цифр, дефис, четыре шестнадцатеричные цифры, дефис, четыре шестнадцатеричные цифры, дефис, четыре шестнадцатеричные цифры, дефис, двенадцать шестнадцатеричных цифр.

Шестнадцатеричный код удваивает все — каждый байт становится двумя символами, а четыре дефиса завершают 36.

Каждый байт становится ровно двумя шестнадцатеричными символами (0–9, a–f). Дефисы используются для удобства чтения и по причинам, устаревшим с момента первого указания UUID. Шестнадцатеричное кодирование удваивает количество байтов: 16 bytes превращается в 32 шестнадцатеричных цифр плюс 4 дефисов. Это самая медленная и самая длинная кодировка, но удобочитаемая и поддерживаемая везде. Правила регистра: RFC 9562 требует использования нижнего регистра для канонического вывода, но ввод нечувствителен к регистру. Сохранение верхнего регистра приводит к потере возможности нормализации, поэтому сохраняйте строчные буквы и сравнивайте входные данные без учета регистра. Кодировка Base64url представляет три байта как четыре символа с использованием 64-символьного алфавита (A–Z, a–z, 0–9, минус, подчеркивание). Шестнадцать байтов превращаются в 21 символов плюс один заполняющий символ, всего 22 символов. Base64url удаляет отступы и стандартные символы (плюс и косая черта), зарезервированные в URL-адресах.

Правила регистра — строчные буквы при выводе, регистронезависимость при вводе и почему сравнения в смешанном регистре вызывают молчаливые несоответствия.

UUID в формате base64url сохраняет 14 символов по сравнению с шестнадцатеричным и действителен в URL-адресах без процентного кодирования. Компромисс: он менее читаем (строчные буквы выглядят как цифры; b, 8, B и 8 легко перепутать). Base58 используется Биткойном и другими блокчейнами и удаляет неоднозначные символы (0, O, I, l), делая результат 22–23 символами, оставаясь при этом читабельными. Crockford base32 (разработанный для форматов, подобных ISBN с контрольной суммой) использует символы 26 и отдает приоритет правильности над краткостью. Ловушка порядка байтов Microsoft GUID применяется к хранилищу UUID в некоторых базах данных. RFC 9562 определяет сетевой порядок байтов (обратный порядок байтов) для всех байтов. Некоторые конфигурации сервера Microsoft SQL хранят GUID с прямым порядком байтов в первых трех полях.

Более короткие кодировки — base64url с 22 символов, base58 и Crockford base32, с их компромиссами в читаемости и безопасности копирования-вставки.

Одно и то же 128-битное значение, хранящееся в формате с прямым порядком байтов и прямым порядком байтов, создает разные шестнадцатеричные строки. UUID 550e8400-e29b-41d4-a716-446655440000, хранящийся как Microsoft GUID, может быть получен как 00840e55-9be2-d441-a716-446655440000 (байты 0–3 и 4–5 и 6–7 поменялись местами). Если ваша система является мостом между RFC-совместимыми и системами Microsoft, вы должны знать об этом и либо нормализовать границу, либо документировать, какой формат вы используете в каждом столбце. Рабочий пример: v4 UUID 9b2e4f1a-4f3e-4c1a-8a7d-1b2c3d4e5f60 в шестнадцатеричном формате занимает 36 символов. В качестве 16 bytes это 9b 2e 4f 1a 4f 3e 4c 1a 8a 7d 1b 2c 3d 4e 5f 60. В base64url: разделить на трехбайтовые фрагменты, преобразовать в base64, удалить заполнение: my5PGk8-TBqKfRssPTRPX2A. В шестнадцатеричном формате без дефисов: 9b2e4f1a4f3e4c1a8a7d1b2c3d4e5f60 (32 символов).

Ловушка порядка байтов Microsoft — как первые три поля GUID хранятся с прямым порядком байтов, поэтому одни и те же байты могут печататься как две разные строки.

Base64url сохраняет 14 символов; base58 сохранит примерно то же самое; шестнадцатеричный формат является стандартом. Выбирайте в зависимости от вашего варианта использования: если идентификатор появляется в URL-адресах и каждый символ имеет значение, используйте base64url; если он появляется в журналах и пользовательских интерфейсах, где его читают люди, используйте шестнадцатеричную каноническую форму; Если вы создаете систему блокчейна или распределенную систему, где контрольная сумма имеет значение, используйте base58 или Crockford base32. При выборе типа столбца сохраните значение, которое оптимизируется для вашего фактического шаблона доступа. Если вы часто запрашиваете UUID и вам требуется сопоставление без учета регистра, сохраните двоичный файл (16) и позвольте базе данных обрабатывать представление. Если вы выполняете запрос по подстроке (поиск UUID, начинающихся с префикса), шестнадцатеричный формат более читабелен в выводе отладки.

Рабочий пример — один идентификатор, записанный в байтах, каноническом шестнадцатеричном формате и сокращенной форме, показывающий каждый шаг преобразования.

Если вы экспортируете в CSV и отправляете электронное письмо нетехническим пользователям, шестнадцатеричное число будет более узнаваемым. Если у вас мало места (мобильное приложение с локальным кешем), base64url или base58 экономит полосу пропускания. Генератор ToolAcre выводит канонический шестнадцатеричный формат из 36 символов; если вам нужна другая кодировка, правильно сформированная проверка по-прежнему работает, поскольку она нормализует любое допустимое представление перед проверкой формата. Соображения производительности имеют значение при кодировании или декодировании миллионов UUID. Шестнадцатеричное кодирование простое: преобразуйте каждый байт в два символа за время O(1) на каждый байт. Декодирование одинаково просто. Кодирование и декодирование Base64 используют таблицы поиска и работают немного медленнее (примерно на 2 – в 3 раза медленнее, чем шестнадцатеричный код на байт, в зависимости от оборудования и реализации). Base58 значительно медленнее, поскольку по сути представляет собой базовое преобразование и требует модульной арифметики.

Что здесь не распространяется — варианты столбцов базы данных, такие как собственные типы uuid или двоичный (16), рассматриваются отдельно.

Если ваша система кодирует или декодирует UUID в «горячем» цикле (генерация высокочастотных идентификаторов, массовый экспорт), шестнадцатеричный код работает быстрее. Если кодирование происходит нечасто и важна экономия символов 14, base64url является разумным компромиссом. Генератор ToolAcre выдает шестнадцатеричный результат, поэтому вы получаете преимущество в производительности без ущерба для совместимости. Семантика сравнения строк различается в зависимости от кодировки. Шестнадцатеричные UUID можно сравнивать как строки: 550e8400-e29b-41d4-a716-446655440000 < 550e8400-e29b-41d4-a716-446655440001 (работает лексикографическое сравнение). Двоичные UUID можно сравнивать как байты: побайтовое сравнение аналогично числовому сравнению. Однако UUID в кодировке Base64url и Base58 не сохраняют числовой порядок при лексикографическом сравнении строк. Если ваша система использует лексикографическую сортировку UUID (на удивление распространенный шаблон для построения индексов или ключей базы данных), вы должны использовать шестнадцатеричный, двоичный или сортируемый вариант UUID (v6 или v7).

Вывод: сохраняйте каноническую форму на границах — генератор ToolAcre выводит стандартные UUID из 36 символов, и его проверка принимает строки в этой форме.

Генератор ToolAcre в настоящее время создает UUID версии 4, которые нельзя сортировать по порядку кодирования. Функциональная совместимость требует стандартизации одной кодировки. Система, которая одновременно принимает UUID в шестнадцатеричном формате, base64 и base58, перед обработкой должна нормализовать все входные данные до канонической формы. Это возможно, но добавляет сложности. Для внешних API или баз данных может потребоваться определенная кодировка: некоторые API ожидают urn:uuid: шестнадцатеричный код с префиксом, другие ожидают шестнадцатеричный код без дефиса, третьи ожидают base64url. Четко задокументируйте ожидаемое кодирование UUID вашей системы в контрактах API. Генератор ToolAcre всегда выводит канонический шестнадцатеричный код; если вам нужны другие кодировки, выполните преобразование явно и задокументируйте для команды компромиссы (пространство, производительность, читаемость, сортируемость).