Универсальный уникальный идентификатор ( UUID ) — это 128-битная метка , используемая для уникальной идентификации объектов в компьютерных системах. Термин Глобальный уникальный идентификатор ( GUID ) также используется, в основном в системах Microsoft . [1] [2]
При генерации в соответствии со стандартными методами UUID, для практических целей, являются уникальными. Их уникальность не зависит от центрального регистрационного органа или координации между сторонами, генерирующими их, в отличие от большинства других схем нумерации. Хотя вероятность того , что UUID будет дублирован, не равна нулю, она, как правило, считается достаточно близкой к нулю, чтобы ею можно было пренебречь. [3] [4]
Таким образом, любой может создать UUID и использовать его для идентификации чего-либо с почти полной уверенностью, что идентификатор не дублирует тот, который уже был или будет создан для идентификации чего-либо другого. Поэтому информация, помеченная UUID независимыми сторонами, может быть впоследствии объединена в единую базу данных или передана по тому же каналу с незначительной вероятностью дублирования.
Использование UUID широко распространено, и многие вычислительные платформы поддерживают их генерацию и анализ их текстового представления.
В 1980-х годах Apollo Computer изначально использовала UUID в Network Computing System (NCS). Позже Open Software Foundation (OSF) использовала UUID для своей Distributed Computing Environment (DCE). Дизайн DCE UUID был частично основан на NCS UUID, [5] дизайн которых, в свою очередь, был вдохновлен ( 64-битными ) уникальными идентификаторами, определенными и широко используемыми в Domain/OS , операционной системе , разработанной Apollo Computer. [6] Позже, [ когда? ] платформы Microsoft Windows приняли дизайн DCE как «Глобально уникальные идентификаторы» (GUID).
RFC 4122 зарегистрировал пространство имен URN для UUID и повторил более ранние спецификации с тем же техническим содержанием. [2] Когда в июле 2005 года RFC 4122 был опубликован в качестве предлагаемого стандарта IETF , ITU также стандартизировал UUID на основе предыдущих стандартов и ранних версий RFC 4122. 7 мая 2024 года был опубликован RFC 9562, в котором были представлены 3 новые «версии» и разъяснены некоторые двусмысленности.
UUID стандартизированы Open Software Foundation (OSF) как часть Распределенной вычислительной среды (DCE). [7] [8]
UUID задокументированы как часть ISO / IEC 11578:1996 « Информационные технологии – Взаимосвязь открытых систем – Удаленный вызов процедур (RPC)» и совсем недавно в ITU-T Rec. X.667 | ISO / IEC 9834-8:2014. [9]
Целевая группа по инжинирингу Интернета ( IETF ) опубликовала документ Standards-Track RFC 9562 [1] от «Рабочей группы по пересмотру определений универсальных уникальных идентификаторов» [10] в качестве пересмотренного варианта RFC 4122. [2] RFC 4122 технически эквивалентен ITU-T Rec. X.667 | ISO/IEC 9834-8, но в настоящее время устарел.
UUID имеет размер 128 бит, в котором от 2 до 4 бит используются для указания варианта формата. Наиболее распространенный вариант, используемый сегодня, OSF DCE, дополнительно определяет 4 бита для своей версии.
Использование оставшихся битов регулируется выбранным вариантом/версией.
Поле варианта указывает формат UUID (а в случае устаревшего UUID также семейство адресов, используемых для поля узла). Определены следующие варианты:
0xxx
позволяет избежать конфликтов с историческими UUID NCS, если таковые все еще существуют в базах данных. [11] Этот вариант определяет «семейства» как подтип.Вариант OSF DCE определяет восемь «версий» в стандарте, и каждая версия может быть более подходящей, чем другие в определенных случаях использования. Версия указывается значением старшего полубайта (старшие 4 бита или старшая шестнадцатеричная цифра) 7-го байта UUID. В шестнадцатеричном формате это символ после второго тире. Например, UUID — это версия 4, поскольку цифра после второго тире — 4 в .9c5b94b1-35ad-49bb-b118-8e8fc24abf80
...-49bb-...
Версия 1 объединяет 48-битный MAC-адрес «узла» (то есть компьютера, генерирующего UUID) с 60-битной временной меткой, представляющей собой число 100- наносекундных интервалов с полуночи 15 октября 1582 года по всемирному координированному времени (UTC), даты, когда григорианский календарь был впервые принят большей частью Европы. RFC 4122 утверждает, что значение времени переходит около 3400 года нашей эры, [2] : 3 в зависимости от используемого алгоритма, что подразумевает, что 60-битная временная метка является знаковой величиной. Однако некоторое программное обеспечение, такое как библиотека libuuid, рассматривает временную метку как беззнаковую, помещая время перехода в 5623 год нашей эры. [12] Время перехода, как определено в ITU-T Rec. X.667, составляет 3603 год нашей эры. [13] : v
13-битная или 14-битная «уникифицирующая» последовательность часов расширяет временную метку для обработки случаев, когда процессорные часы продвигаются недостаточно быстро или когда на узел приходится несколько процессоров и генераторов UUID. Когда UUID генерируются быстрее, чем системные часы могут продвигаться, младшие биты полей временной метки могут быть сгенерированы путем увеличения их каждый раз, когда генерируется UUID, для имитации временной метки высокого разрешения. Поскольку каждый UUID версии 1 соответствует одной точке в пространстве (узлу) и времени (интервалам и последовательности часов), вероятность того, что два правильно сгенерированных UUID версии 1 будут непреднамеренно одинаковыми, практически равна нулю. Поскольку последовательность времени и часов составляет в общей сложности 74 бита, 2 74 (1,8 × 10Для каждого идентификатора узла может быть сгенерировано 22 (или 18 секстиллионов) UUID версии 1, со средней максимальной скоростью 163 миллиарда в секунду для каждого идентификатора узла. [2]
В отличие от других версий UUID, UUID версии 1 и версии 2, основанные на MAC-адресах сетевых карт, частично полагаются на идентификатор, выданный центральным регистрационным органом, а именно на часть Организационно-уникального идентификатора (OUI) MAC-адреса, которая выдается IEEE производителям сетевого оборудования. [14] Уникальность UUID версии 1 и версии 2, основанных на MAC-адресах сетевых карт, также зависит от того, правильно ли производители сетевых карт назначают своим картам уникальные MAC-адреса, что, как и другие производственные процессы, подвержено ошибкам. Виртуальные машины получают MAC-адрес в диапазоне, который настраивается в гипервизоре. [15] Кроме того, некоторые операционные системы позволяют конечному пользователю настраивать MAC-адрес, в частности OpenWRT . [16]
Использование MAC-адреса сетевой карты узла для идентификатора узла означает, что UUID версии 1 можно отследить до компьютера, который его создал. Документы иногда можно отследить до компьютеров, где они были созданы или отредактированы, через UUID, встроенные в них программным обеспечением для обработки текстов . Эта дыра в конфиденциальности была использована при поиске создателя вируса Melissa . [17]
RFC 9562 позволяет заменить MAC-адрес в UUID версии 1 (или 2) случайным 48-битным идентификатором узла, либо потому, что у узла нет MAC-адреса, либо потому, что его нежелательно раскрывать. В этом случае RFC требует, чтобы младший бит первого октета идентификатора узла был установлен в 1. [2] Это соответствует биту multicast в MAC-адресах, и его установка служит для различения UUID, где идентификатор узла генерируется случайным образом из UUID на основе MAC-адресов сетевых карт, которые обычно имеют одноадресные MAC-адреса. [2]
Версия 6 такая же, как и версия 1, за исключением того, что все биты временной метки упорядочены от наиболее значимого к наименее значимому. Это позволяет системам сортировать UUID в порядке создания, просто сортируя их лексически, тогда как в версии 1 это невозможно.
RFC 9562 резервирует версию 2 для UUID "DCE security"; но не предоставляет никаких подробностей. По этой причине многие реализации UUID опускают версию 2. Однако спецификация UUID версии 2 предоставляется спецификацией DCE 1.1 Authentication and Security Services. [8]
UUID версии 2 аналогичны версии 1, за исключением того, что наименее значимые 8 бит последовательности часов заменяются номером «локального домена», а наименее значимые 32 бита временной метки заменяются целочисленным идентификатором, имеющим смысл в пределах указанного локального домена. В системах POSIX номера локального домена 0 и 1 предназначены для идентификаторов пользователей ( UID ) и идентификаторов групп ( GID ) соответственно, а другие номера локального домена определяются сайтом. [8] В системах, отличных от POSIX, все номера локального домена определяются сайтом.
Возможность включения 40-битного домена/идентификатора в UUID имеет компромисс. С одной стороны, 40 бит допускают около 1 триллиона значений домена/идентификатора на один идентификатор узла. С другой стороны, при усечении значения часов до 28 наиболее значимых бит, по сравнению с 60 битами в версии 1, часы в версии 2 UUID будут «тикать» только один раз каждые 429,49 секунд, чуть больше 7 минут, в отличие от каждых 100 наносекунд для версии 1. И при последовательности часов всего из 6 бит, по сравнению с 14 битами в версии 1, только 64 уникальных UUID на узел/домен/идентификатор могут быть сгенерированы за 7-минутный тик часов, по сравнению с 16 384 значениями последовательности часов для версии 1. [18]
UUID версий 3 и 5 генерируются путем хеширования идентификатора пространства имен и имени. Версия 3 использует MD5 в качестве алгоритма хеширования, а версия 5 использует SHA-1 . [1]
Идентификатор пространства имен сам по себе является UUID. Спецификация предоставляет UUID для представления пространств имен для URL-адресов , полных доменных имен , идентификаторов объектов и различающихся имен X.500 ; но любой желаемый UUID может использоваться в качестве указателя пространства имен.
Чтобы определить UUID версии 3, соответствующий данному пространству имен и имени, UUID пространства имен преобразуется в строку байтов, конкатенируется с входным именем, затем хэшируется с помощью MD5, что дает 128 бит. Затем 6 или 7 бит заменяются фиксированными значениями, 4-битной версией (например, 0011 2 для версии 3) и 2- или 3-битным «вариантом» UUID (например, 10 2, указывающим на UUID RFC 9562, или 110 2, указывающим на устаревший Microsoft GUID). Поскольку 6 или 7 бит, таким образом, предопределены, только 121 или 122 бита вносят вклад в уникальность UUID.
UUID версии 5 похожи, но вместо MD5 используется SHA-1. Поскольку SHA-1 генерирует 160-битные дайджесты, дайджест усекается до 128 бит перед заменой битов версии и варианта.
UUID версии 3 и версии 5 обладают свойством, что одно и то же пространство имен и имя будут отображаться в один и тот же UUID. Однако ни пространство имен, ни имя не могут быть определены из UUID, даже если один из них указан, за исключением поиска методом подбора. RFC 4122 рекомендует версию 5 (SHA-1) вместо версии 3 (MD5) и предостерегает от использования UUID любой из версий в качестве учетных данных безопасности. [2]
UUID версии 4 генерируется случайным образом. Как и в других UUID, 4 бита используются для указания версии 4, и 2 или 3 бита для указания варианта (10 2 или 110 2 для вариантов 1 и 2 соответственно). Таким образом, для варианта 1 (то есть большинства UUID) случайный UUID версии 4 будет иметь 6 предопределенных битов варианта и версии, оставляя 122 бита для случайно сгенерированной части, что в общей сложности составляет 2 122 , или 5,3 × 1036 (5,3 ундециллиона ) возможных UUID версии 4 варианта 1. Существует вдвое меньше возможных UUID версии 4 варианта 2 (устаревшие GUID), поскольку доступно на один случайный бит меньше, 3 бита потребляются для варианта.
Согласно RFC 9562, 4 самых значимых бита седьмого октета указывают, какой версии соответствует UUID. Это означает, что первая шестнадцатеричная цифра в третьей группе всегда начинается с a в UUIDv4s. Визуально это выглядит так , где — поле версии UUID. Верхние два или три бита цифры кодируют вариант. Значениями являются , , или для 2-битного указания, значениями или для 3-битного указания. Например, случайная версия UUID 4, вариант 2 может быть . [19]4
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
M
N
8
9
A
B
C
D
8D8AC610-566D-4EF0-9C22-186B2A5ED793
UUID версии 7 (UUIDv7) предназначены для ключей в высоконагруженных базах данных и распределенных системах.
UUIDv7 начинается с 48-битной метки времени Unix Epoch с обратным порядком байтов и приблизительно миллисекундной гранулярностью. Метка времени может быть сдвинута на любое значение сдвига времени. Сразу после метки времени следует полубайт версии, который должен иметь значение 7. Биты варианта должны быть 10x
. Оставшиеся 74 бита — это случайный сеяный счетчик (необязательно, не менее 12 бит, но не более 42 бит) и случайные.
Два метода обработки опрокидывания счетчика могут использоваться совместно:
В СУБД генератор UUIDv7 может быть общим для потоков (привязанным к таблице или к экземпляру СУБД) или может быть локальным для потока (с худшими монотонностью, локальностью и производительностью).
Версия 8 имеет только два требования:
10x
.Эти требования сообщают системе, что это UUID версии 8. Остальные 122 бита настраиваются поставщиком. Разница с версией 4 в том, что эти 122 бита случайны, а 122 бита в UUID версии 8 — нет, поскольку они следуют правилам, определенным поставщиком.
UUID «nil» — это UUID 00000000-0000-0000-0000-000000000000
, то есть все биты установлены в ноль. [1]
«Максимальный» UUID, иногда также называемый «всеобщим» UUID, — это UUID FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF
, то есть все биты которого установлены в единицу. [1]
Первоначально компания Apollo Computer разработала UUID со следующим форматом провода: [5] [11]
Позже UUID был расширен путем объединения устаревшего поля семейства с новым полем варианта. Поскольку поле семейства в прошлом использовало только значения от 0 до 13, было решено, что UUID с самым значимым битом, установленным на 0, является устаревшим UUID. Это дает следующую таблицу для группы семейства:
Устаревший Apollo NCS UUID имеет формат, описанный в предыдущей таблице. Вариант OSF DCE UUID описан в RFC 9562. Microsoft COM / DCOM UUID имеет свой вариант, описанный в документации Microsoft.
При сохранении UUID в двоичном формате они последовательно кодируются в big-endian . Например, 00112233-4455-6677-8899-aabbccddeeff
кодируется как байты 00 11 22 33
44 55
66 77
88 99
aa bb cc dd ee ff
. [21] [22]
Исключением из этого правила являются идентификаторы UUID варианта 2 («GUID») от Microsoft: исторически используемые в библиотеках COM/OLE , они используют формат с прямым порядком байтов , но выглядят как смешанные, с первыми тремя компонентами UUID с прямым порядком байтов , а последними двумя — с обратным порядком байтов , из-за отсутствующих байтовых дефисов при форматировании в виде строки. [23] Например, 00112233-4455-6677-8899-aabbccddeeff
кодируется как байты 33 22 11 00
55 44
77 66
88 99
aa bb cc dd ee ff
. [24] [25]
В большинстве случаев UUID представлены в виде шестнадцатеричных значений. Наиболее используемый формат — это формат 8-4-4-4-12, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
где каждый x
представляет 4 бита. Другие известные форматы — это формат 8-4-4-4-12 с фигурными скобками, {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
как в системах Microsoft, например, Windows, или xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
, где все дефисы удалены. В некоторых случаях также возможно использовать xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
префикс «0x» или суффикс «h» для указания шестнадцатеричных значений. Формат с дефисами был введен в новой системе вариантов. До этого устаревший формат Apollo использовал немного другой формат: 34dc23469000.0d.00.00.7c.5f.00.00.00
. Первая часть — это время (time_high и time_low вместе). Зарезервированное поле пропускается. Поле семейства идет сразу после первой точки, поэтому в этом случае 0d
(13 в десятичной системе) для DDS (Data Distribution Service) . Остальные части, каждая из которых разделена точкой, — это байты узла.
Формат шестнадцатеричных значений в нижнем регистре является, как правило, предпочтительным форматом. В частности, в некоторых контекстах, таких как те, которые определены в Рекомендации ITU-T X.667, при генерации текста требуется использовать нижний регистр, но версия в верхнем регистре также должна быть принята.
UUID может быть представлен как 128-битное целое число. Например, UUID 550e8400-e29b-41d4-a716-446655440000
также может быть представлен как 113059749145936325402354257176981405696. Обратите внимание, что возможны как знаковые, так и беззнаковые значения, если первый бит UUID установлен в 1.
UUID может быть представлен как 128-битное двоичное число . Например, UUID 550e8400-e29b-41d4-a716-446655440000
также может быть представлен как 0101010100001110100001000000000111000101001101101000001110101001010011100010110010001000110011001010101010001000000000000000.
RFC 9562 регистрирует пространство имен "uuid". Это позволяет создавать URN из UUID, например urn:uuid:550e8400-e29b-41d4-a716-446655440000
. Для этого используется обычный формат 8-4-4-4-12. Также возможно создавать OID URN из UUID, например urn:oid:2.25.113059749145936325402354257176981405696
. В этом случае используется беззнаковый десятичный формат. URN "uuid" рекомендуется использовать вместо URN "oid".
Коллизия происходит, когда один и тот же UUID генерируется более одного раза и назначается разным референтам. В случае стандартных UUID версии 1 и версии 2, использующих уникальные MAC-адреса сетевых карт, коллизии маловероятны, и вероятность увеличивается только тогда, когда реализация отличается от стандартов, как непреднамеренно, так и преднамеренно.
В отличие от UUID версии 1 и версии 2, сгенерированных с использованием MAC-адресов, с UUID версии 1 и -2, которые используют случайно сгенерированные идентификаторы узлов, UUID версии 3 и версии 5 на основе хэша и случайные UUID версии 4, коллизии могут происходить даже без проблем реализации, хотя и с вероятностью настолько малой, что ее обычно можно игнорировать. Эту вероятность можно точно вычислить на основе анализа проблемы дня рождения . [26]
Например, количество случайных UUID версии 4, которые необходимо сгенерировать для того, чтобы иметь 50% вероятность хотя бы одного столкновения, составляет 2,71 квинтиллиона и вычисляется следующим образом: [27]
Это число эквивалентно генерации 1 миллиарда UUID в секунду в течение примерно 86 лет. Файл, содержащий столько UUID, по 16 байт на UUID, будет иметь размер около 45 эксабайт .
Наименьшее количество идентификаторов UUID версии 4, которое необходимо сгенерировать для того, чтобы вероятность обнаружения коллизии была равна p, аппроксимируется формулой
Таким образом, вероятность найти дубликат среди 103 триллионов UUID версии 4 составляет один к миллиарду.
Коллизии происходили, когда производители назначали UUID по умолчанию продукту, например материнской плате, а затем не перезаписывали UUID по умолчанию позже в процессе производства. Например, UUID 03000200-0400-0500-0006-000700080009 встречается на многих различных единицах материнских плат марки Gigabyte . [28]
Значительные применения включают в себя инструменты пользовательского пространства файловой системы ext2 / ext3 / ext4 ( e2fsprogs использует libuuid, предоставленный util-linux ), LVM , зашифрованные разделы LUKS , GNOME , KDE и macOS , [29] большинство из которых получены из оригинальной реализации Теодора Цо . [12]
«Метка раздела» и «UUID раздела» оба хранятся в суперблоке . Они оба являются частью файловой системы, а не раздела. Например, ext2–4 содержат UUID, в то время как NTFS или FAT32 — нет. Суперблок является частью файловой системы, таким образом, полностью содержится в разделе, следовательно, dd if=/dev/sda1 of=/dev/sdb1
и sda1, и sdb1 остаются с той же меткой и UUID.
В компонентной объектной модели Microsoft (COM) используются несколько разновидностей GUID :
[HKEY_CLASSES_ROOT\Interface]
[30] )[HKEY_CLASSES_ROOT\CLSID]
)[HKEY_CLASSES_ROOT\TypeLib]
[31] )[HKEY_CLASSES_ROOT\Component Categories]
[32] )UUID обычно используются в качестве уникального ключа в таблицах базы данных . Функция NEWID в Microsoft SQL Server версии 4 Transact-SQL возвращает стандартные случайные UUID версии 4, в то время как функция NEWSEQUENTIALID возвращает 128-битные идентификаторы, похожие на UUID, которые обязуются возрастать по порядку до следующей перезагрузки системы. [33] Функция Oracle Database SYS_GUID не возвращает стандартный GUID, несмотря на название. Вместо этого она возвращает 16-байтовое 128-битное значение RAW на основе идентификатора хоста и идентификатора процесса или потока, несколько похожее на GUID. [34] PostgreSQL содержит тип данных UUID [35] и может генерировать большинство версий UUID с помощью функций из модулей. [36] [37] MySQL предоставляет функцию UUID , которая генерирует стандартные UUID версии 1. [38]
Случайная природа стандартных UUID версий 3, 4 и 5, а также порядок полей в стандартных версиях 1 и 2 могут создавать проблемы с локальностью или производительностью базы данных, когда UUID используются в качестве первичных ключей . Например, в 2002 году Джимми Нильссон сообщил о значительном улучшении производительности с Microsoft SQL Server, когда UUID версии 4, используемые в качестве ключей, были изменены для включения неслучайного суффикса на основе системного времени. Этот так называемый подход «COMB» (комбинированное время-GUID) значительно повысил вероятность дублирования UUID, как признал Нильссон, но Нильссон требовал уникальности только в пределах приложения. [39] Переупорядочивая и кодируя UUID версий 1 и 2 так, чтобы временная метка шла первой, можно избежать потери производительности вставки. [40]
Соответствующие COMB-подобные структуры полезных нагрузок UUID в конечном итоге были стандартизированы в RFC 9562 как UUIDv6 и UUIDv7.
ссылаетесь на интерфейс во время выполнения с помощью глобально уникального идентификатора интерфейса (
IID
). Этот
IID
, который является конкретным экземпляром глобально уникального идентификатора (
GUID
), поддерживаемого COM, позволяет клиенту точно спрашивать объект, поддерживает ли он семантику интерфейса, без ненужных накладных расходов и без путаницы, которая может возникнуть в системе из-за наличия нескольких версий одного и того же интерфейса с одинаковым именем.
CATID и понятных человеку имен хранится в известном месте в реестре.