Un identificador único universal ( UUID ) es una etiqueta de 128 bits que se utiliza para la información en los sistemas informáticos. El término identificador único global ( GUID ) también se utiliza, sobre todo en los sistemas de Microsoft. [1] [2]
Cuando se generan según los métodos estándar, los UUID son, a efectos prácticos, únicos. Su unicidad no depende de una autoridad de registro central ni de la coordinación entre las partes que los generan, a diferencia de la mayoría de los demás esquemas de numeración. Si bien la probabilidad de que un UUID se duplique no es cero, generalmente se considera que es lo suficientemente cercana a cero como para ser insignificante. [3] [4]
De esta manera, cualquiera puede crear un UUID y usarlo para identificar algo con casi total certeza de que el identificador no duplica a otro que ya se haya creado o se vaya a crear para identificar otra cosa. Por lo tanto, la información etiquetada con UUID por partes independientes puede combinarse posteriormente en una única base de datos o transmitirse por el mismo canal, con una probabilidad insignificante de duplicación.
La adopción de UUID está muy extendida y muchas plataformas informáticas ofrecen soporte para generarlos y analizar su representación textual.
En la década de 1980, Apollo Computer utilizó originalmente UUID en el Network Computing System (NCS). Más tarde, la Open Software Foundation (OSF) utilizó UUID para su entorno informático distribuido (DCE). El diseño de los UUID del DCE se basó en parte en los UUID del NCS, [5] cuyo diseño se inspiró a su vez en los identificadores únicos ( de 64 bits ) definidos y utilizados de forma generalizada en Domain/OS , un sistema operativo diseñado por Apollo Computer. [6] Más tarde, [ ¿cuándo? ] las plataformas Microsoft Windows adoptaron el diseño del DCE como "identificadores únicos globales" (GUID).
RFC 4122 registró un espacio de nombres URN para UUID y recapituló las especificaciones anteriores, con el mismo contenido técnico. [2] Cuando en julio de 2005 RFC 4122 se publicó como una propuesta de estándar IETF , la UIT también había estandarizado los UUID, basándose en los estándares anteriores y las primeras versiones de RFC 4122. El 7 de mayo de 2024, se publicó RFC 9562, que introdujo 3 nuevas "versiones" y aclaró algunas ambigüedades.
Los UUID están estandarizados por la Open Software Foundation (OSF) como parte del Entorno de Computación Distribuida (DCE). [7] [8]
Los UUID están documentados como parte de la norma ISO / IEC 11578:1996 “ Tecnología de la información – Interconexión de sistemas abiertos – Llamada a procedimiento remoto (RPC)” y más recientemente en la Rec. UIT-T X.667 | ISO / IEC 9834-8:2014. [9]
El Grupo de Trabajo de Ingeniería de Internet (IETF) publicó el RFC 9562 de seguimiento de estándares [1] del "Grupo de trabajo de revisión de definiciones de identificadores universalmente únicos" [10] como revisión del RFC 4122. [2] El RFC 4122 es técnicamente equivalente a la Rec. UIT-T X.667 | ISO/IEC 9834-8, pero ahora está obsoleto.
Un UUID tiene un tamaño de 128 bits, en el que se utilizan de 2 a 4 bits para indicar la variante del formato. La variante más común en uso hoy en día, OSF DCE, define además 4 bits para su versión.
El uso de los bits restantes está regido por la variante/versión seleccionada.
El campo de variante indica el formato del UUID (y en el caso del UUID heredado, también la familia de direcciones utilizada para el campo de nodo). Se definen las siguientes variantes:
0xxx
evita conflictos con los UUID NCS históricos, en caso de que aún exista alguno en las bases de datos. [11] Esta variante define "familias" como subtipo.La variante OSF DCE define ocho "versiones" en el estándar, y cada versión puede ser más apropiada que las demás en casos de uso específicos. La versión se indica mediante el valor del nibble más alto (los 4 bits más altos o el dígito hexadecimal más alto) del séptimo byte del UUID. En hexadecimal, este es el carácter después del segundo guión. Por ejemplo, el UUID es la versión 4, debido a que el dígito después del segundo guión es 4 en .9c5b94b1-35ad-49bb-b118-8e8fc24abf80
...-49bb-...
La versión 1 concatena la dirección MAC de 48 bits del "nodo" (es decir, el ordenador que genera el UUID), con una marca de tiempo de 60 bits, que es el número de intervalos de 100 nanosegundos desde la medianoche del 15 de octubre de 1582 según el Tiempo Universal Coordinado (UTC), la fecha en la que el calendario gregoriano fue adoptado por primera vez por la mayor parte de Europa. El RFC 4122 establece que el valor de tiempo se desplaza alrededor del 3400 d. C., [2] : 3 dependiendo del algoritmo utilizado, lo que implica que la marca de tiempo de 60 bits es una cantidad con signo. Sin embargo, algunos programas, como la biblioteca libuuid, tratan la marca de tiempo como sin signo, lo que pone el tiempo de desplazamiento en 5623 d. C. [12] El tiempo de desplazamiento según lo definido por la Rec. X.667 de la UIT-T es 3603 d. C. [13] : v
Una secuencia de reloj "uniquificadora" de 13 o 14 bits extiende la marca de tiempo para manejar casos donde el reloj del procesador no avanza lo suficientemente rápido, o donde hay múltiples procesadores y generadores de UUID por nodo. Cuando los UUID se generan más rápido de lo que el reloj del sistema podría avanzar, los bits inferiores de los campos de marca de tiempo se pueden generar incrementándolos cada vez que se genera un UUID, para simular una marca de tiempo de alta resolución. Con cada UUID de la versión 1 correspondiente a un único punto en el espacio (el nodo) y el tiempo (intervalos y secuencia de reloj), la probabilidad de que dos UUID de la versión 1 generados correctamente sean involuntariamente iguales es prácticamente nula. Dado que la secuencia de tiempo y reloj suman 74 bits, 2 74 (1,8 × 10Se pueden generar 22 o 18 sextillones) de UUID de la versión 1 por cada ID de nodo, a una tasa promedio máxima de 163 mil millones por segundo por cada ID de nodo. [2]
A diferencia de otras versiones de UUID, los UUID de las versiones 1 y 2 basados en direcciones MAC de tarjetas de red dependen, para su unicidad, en parte de un identificador emitido por una autoridad de registro central, a saber, la parte del identificador único organizacional (OUI) de la dirección MAC, que emite el IEEE a los fabricantes de equipos de red. [14] La unicidad de los UUID de las versiones 1 y 2 basados en direcciones MAC de tarjetas de red también depende de que los fabricantes de tarjetas de red asignen correctamente direcciones MAC únicas a sus tarjetas, lo que, como otros procesos de fabricación, está sujeto a errores. Las máquinas virtuales reciben una dirección MAC en un rango que se puede configurar en el hipervisor. [15] Además, algunos sistemas operativos permiten al usuario final personalizar la dirección MAC, en particular OpenWRT . [16]
El uso de la dirección MAC de la tarjeta de red del nodo para el ID del nodo significa que un UUID de la versión 1 puede rastrearse hasta la computadora que lo creó. A veces, los documentos pueden rastrearse hasta las computadoras donde fueron creados o editados a través de UUID incrustados en ellos por software de procesamiento de textos . Este agujero de privacidad se utilizó para localizar al creador del virus Melissa . [17]
El RFC 9562 permite que la dirección MAC en un UUID de la versión 1 (o 2) se reemplace por un ID de nodo aleatorio de 48 bits, ya sea porque el nodo no tiene una dirección MAC o porque no es deseable exponerlo. En ese caso, el RFC requiere que el bit menos significativo del primer octeto del ID de nodo se establezca en 1. [2] Esto corresponde al bit de multidifusión en las direcciones MAC, y su configuración sirve para diferenciar los UUID en los que el ID de nodo se genera aleatoriamente de los UUID basados en direcciones MAC de tarjetas de red, que normalmente tienen direcciones MAC de unidifusión . [2]
La versión 6 es igual a la versión 1, excepto que todos los bits de marca de tiempo están ordenados del más significativo al menos significativo. Esto permite que los sistemas ordenen los UUID en el orden de creación simplemente ordenándolos léxicamente, mientras que esto no es posible con la versión 1.
RFC 9562 reserva la versión 2 para los UUID de "seguridad DCE", pero no proporciona detalles. Por este motivo, muchas implementaciones de UUID omiten la versión 2. Sin embargo, la especificación de los UUID de la versión 2 se proporciona en la especificación de servicios de seguridad y autenticación DCE 1.1. [8]
Los UUID de la versión 2 son similares a la versión 1, excepto que los 8 bits menos significativos de la secuencia de reloj se reemplazan por un número de "dominio local", y los 32 bits menos significativos de la marca de tiempo se reemplazan por un identificador entero significativo dentro del dominio local especificado. En los sistemas POSIX , los números de dominio local 0 y 1 son para los identificadores de usuario ( UID ) y los identificadores de grupo ( GID ) respectivamente, y otros números de dominio local están definidos por el sitio. [8] En los sistemas que no son POSIX, todos los números de dominio local están definidos por el sitio.
La capacidad de incluir un dominio/identificador de 40 bits en el UUID tiene una desventaja. Por un lado, 40 bits permiten aproximadamente 1 billón de valores de dominio/identificador por ID de nodo. Por otro lado, con el valor del reloj truncado a los 28 bits más significativos, en comparación con los 60 bits de la versión 1, el reloj en un UUID de la versión 2 "marcará" solo una vez cada 429,49 segundos, un poco más de 7 minutos, en comparación con cada 100 nanosegundos de la versión 1. Y con una secuencia de reloj de solo 6 bits, en comparación con los 14 bits de la versión 1, solo se pueden generar 64 UUID únicos por nodo/dominio/identificador por cada marca de reloj de 7 minutos, en comparación con los 16.384 valores de secuencia de reloj de la versión 1. [18]
Los UUID de las versiones 3 y 5 se generan mediante el algoritmo hash de un identificador de espacio de nombres y un nombre. La versión 3 utiliza MD5 como algoritmo hash, y la versión 5 utiliza SHA-1 . [1]
El identificador de espacio de nombres es en sí mismo un UUID. La especificación proporciona UUID para representar los espacios de nombres para URL , nombres de dominio completos , identificadores de objetos y nombres distinguidos X.500 ; pero cualquier UUID deseado puede usarse como designador de espacio de nombres.
Para determinar el UUID de la versión 3 correspondiente a un nombre y espacio de nombres dados, el UUID del espacio de nombres se transforma en una cadena de bytes, se concatena con el nombre de entrada y luego se codifica con MD5, lo que da como resultado 128 bits. Luego, se reemplazan 6 o 7 bits por valores fijos, la versión de 4 bits (por ejemplo, 0011 2 para la versión 3) y la "variante" del UUID de 2 o 3 bits (por ejemplo, 10 2 indica un UUID RFC 9562 o 110 2 indica un GUID Microsoft heredado). Dado que 6 o 7 bits están predeterminados, solo 121 o 122 bits contribuyen a la unicidad del UUID.
Los UUID de la versión 5 son similares, pero se utiliza SHA-1 en lugar de MD5. Dado que SHA-1 genera resúmenes de 160 bits, el resumen se trunca a 128 bits antes de reemplazar los bits de la versión y la variante.
Los UUID de las versiones 3 y 5 tienen la propiedad de que el mismo espacio de nombres y nombre se asignarán al mismo UUID. Sin embargo, ni el espacio de nombres ni el nombre se pueden determinar a partir del UUID, incluso si se especifica uno de ellos, excepto mediante una búsqueda de fuerza bruta. RFC 4122 recomienda la versión 5 (SHA-1) en lugar de la versión 3 (MD5) y advierte contra el uso de UUID de cualquiera de las dos versiones como credenciales de seguridad. [2]
Un UUID de la versión 4 se genera aleatoriamente. Como en otros UUID, se utilizan 4 bits para indicar la versión 4 y 2 o 3 bits para indicar la variante (10 2 o 110 2 para las variantes 1 y 2 respectivamente). Por lo tanto, para la variante 1 (es decir, la mayoría de los UUID), un UUID de la versión 4 aleatorio tendrá 6 bits de variante y versión predeterminados, dejando 122 bits para la parte generada aleatoriamente, para un total de 2 122 , o 5,3 × 1036 (5,3 undecillones ) posibles UUID de la versión 4, variante 1. Hay la mitad de posibles UUID de la versión 4, variante 2 (GUID heredados) porque hay un bit aleatorio menos disponible, ya que se consumen 3 bits para la variante.
Según RFC 9562, los 4 bits más significativos del séptimo octeto indican a qué versión se adhiere el UUID. Esto significa que el primer dígito hexadecimal del tercer grupo siempre comienza con un en los UUIDv4. Visualmente, esto se ve así , donde es el campo de versión del UUID. Los dos o tres bits superiores del dígito codifican la variante. Por ejemplo, una versión 4 de UUID aleatoria, la variante 2 podría ser . [19]4
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
M
N
8D8AC610-566D-4EF0-9C22-186B2A5ED793
Los UUID de la versión 7 (UUIDv7) están diseñados para claves en bases de datos de alta carga y sistemas distribuidos.
UUIDv7 comienza con una marca de tiempo Epoch Unix big-endian de 48 bits con una granularidad de aproximadamente milisegundos. La marca de tiempo se puede cambiar por cualquier valor de cambio de tiempo. Inmediatamente después de la marca de tiempo sigue el nibble de versión, que debe tener un valor de 7. Los bits de variante deben ser 10x
. Los 74 bits restantes son aleatorios y de contador inicializado (opcional, al menos 12 bits pero no más de 42 bits).
Se pueden utilizar conjuntamente dos métodos de gestión de vuelcos de contador:
En DBMS, el generador UUIDv7 se puede compartir entre subprocesos (vinculado a una tabla o a una instancia DBMS) o puede ser local del subproceso (con peor monotonía, localidad y rendimiento).
La versión 8 solo tiene dos requisitos:
10x
.Estos requisitos indican al sistema que se trata de un UUID de la versión 8. El proveedor debe personalizar los 122 bits restantes. La diferencia con la versión 4 es que esos 122 bits son aleatorios, pero los 122 bits de la versión 8 del UUID no lo son, porque siguen reglas específicas del proveedor.
El UUID "nil" es el UUID 00000000-0000-0000-0000-000000000000
; es decir, todos los bits establecidos en cero. [1]
El UUID "máximo", a veces también llamado UUID "omni", es el UUID FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF
; es decir, todos los bits establecidos en uno. [1]
Inicialmente, Apollo Computer diseñó el UUID con el siguiente formato de cable: [5] [11]
Más tarde, el UUID se amplió combinando el campo de familia heredado con el nuevo campo de variante. Debido a que el campo de familia solo había utilizado los valores que iban de 0 a 13 en el pasado, se decidió que un UUID con el bit más significativo establecido en 0 era un UUID heredado. Esto da como resultado la siguiente tabla para el grupo de familia:
El UUID NCS de Apollo heredado tiene el formato descrito en la tabla anterior. La variante del UUID DCE de OSF se describe en RFC 9562. El UUID COM/DCOM de Microsoft tiene su variante descrita en la documentación de Microsoft.
Al guardar los UUID en formato binario, se codifican secuencialmente en big-endian . Por ejemplo, 00112233-4455-6677-8899-aabbccddeeff
se codifica como bytes 00 11 22 33
44 55
66 77
88 99
aa bb cc dd ee ff
. [21] [22]
Una excepción a esto son los UUID de la variante 2 de Microsoft ("GUID"): históricamente utilizados en bibliotecas COM/OLE , utilizan un formato little-endian , pero aparecen en formato mixed-endian con los primeros tres componentes del UUID como little-endian y los dos últimos big-endian , debido a los guiones de bytes faltantes cuando se formatea como una cadena. [23] Por ejemplo, 00112233-4455-6677-8899-aabbccddeeff
se codifica como bytes 33 22 11 00
55 44
77 66
88 99
aa bb cc dd ee ff
. [24] [25]
En la mayoría de los casos, los UUID se representan como valores hexadecimales. El formato más utilizado es el formato 8-4-4-4-12, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
, donde cada x
representa 4 bits. Otros formatos conocidos son el formato 8-4-4-4-12 con llaves, {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
, como en los sistemas de Microsoft, por ejemplo Windows, o xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
, donde se eliminan todos los guiones. En algunos casos, también es posible tener xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
con el prefijo "0x" o el sufijo "h" para indicar valores hexadecimales. El formato con guiones se introdujo con el sistema de variantes más nuevo. Antes de eso, el formato heredado Apollo usaba un formato ligeramente diferente: 34dc23469000.0d.00.00.7c.5f.00.00.00
. La primera parte es la hora (time_high y time_low combinados). Se omite el campo reservado. El campo de familia viene directamente después del primer punto, por lo que en este caso 0d
(13 en decimal) para DDS (Data Distribution Service) . Las partes restantes, cada una separada por un punto, son los bytes del nodo.
La forma en minúsculas de los valores hexadecimales es el formato generalmente preferido. En algunos contextos, como los definidos en la Rec. X.667 de la UIT-T, se requieren minúsculas cuando se genera el texto, pero también se debe aceptar la versión en mayúsculas.
Un UUID se puede representar como un entero de 128 bits. Por ejemplo, el UUID 550e8400-e29b-41d4-a716-446655440000
también se puede representar como 113059749145936325402354257176981405696. Tenga en cuenta que es posible tener valores con y sin signo si el primer bit del UUID se establece en 1.
Un UUID se puede representar como un número binario de 128 bits . Por ejemplo, el UUID 550e8400-e29b-41d4-a716-446655440000
también se puede representar como 01010101000011101000010000000000111000101001101101000001110101001010011100010110 ...
RFC 9562 registra el espacio de nombres "uuid". Esto permite crear URN a partir de UUID, como urn:uuid:550e8400-e29b-41d4-a716-446655440000
. Para ello se utiliza el formato normal 8-4-4-4-12. También es posible crear una URN OID a partir de UUID, como urn:oid:2.25.113059749145936325402354257176981405696
. En ese caso, se utiliza el formato decimal sin signo. Se recomienda la URN "uuid" en lugar de la URN "oid".
Se produce una colisión cuando se genera el mismo UUID más de una vez y se le asigna a diferentes referentes. En el caso de los UUID de las versiones 1 y 2 estándar que utilizan direcciones MAC únicas de tarjetas de red, es poco probable que se produzcan colisiones, y la posibilidad aumenta solo cuando una implementación varía de los estándares, ya sea de manera inadvertida o intencional.
A diferencia de los UUID de las versiones 1 y 2 generados mediante direcciones MAC, con los UUID de las versiones 1 y 2 que utilizan identificadores de nodo generados aleatoriamente, los UUID de las versiones 3 y 5 basados en hash y los UUID de la versión 4 aleatorios, pueden producirse colisiones incluso sin problemas de implementación, aunque con una probabilidad tan pequeña que normalmente puede ignorarse. Esta probabilidad puede calcularse con precisión basándose en el análisis del problema del cumpleaños . [26]
Por ejemplo, la cantidad de UUID aleatorios de versión 4 que se deben generar para tener una probabilidad del 50 % de al menos una colisión es 2,71 quintillones, que se calcula de la siguiente manera: [27]
Esta cifra equivale a generar mil millones de UUID por segundo durante aproximadamente 86 años. Un archivo que contenga esta cantidad de UUID, a razón de 16 bytes por UUID, equivaldría a unos 45 exabytes .
La cantidad más pequeña de UUID de la versión 4 que se deben generar para que la probabilidad de encontrar una colisión sea p se aproxima mediante la fórmula
Por lo tanto, la probabilidad de encontrar un duplicado dentro de 103 billones de UUID de la versión 4 es de una en mil millones.
Se han producido colisiones cuando los fabricantes asignan un UUID predeterminado a un producto, como una placa base, y luego no sobrescriben el UUID predeterminado más adelante en el proceso de fabricación. Por ejemplo, el UUID 03000200-0400-0500-0006-000700080009 aparece en muchas unidades diferentes de placas base de la marca Gigabyte . [28]
Los usos significativos incluyen herramientas de espacio de usuario del sistema de archivos ext2 / ext3 / ext4 ( e2fsprogs usa libuuid proporcionado por util-linux ), LVM , particiones cifradas LUKS , GNOME , KDE y macOS , [29] la mayoría de las cuales se derivan de la implementación original de Theodore Ts'o . [12]
La "etiqueta de partición" y el "UUID de partición" se almacenan en el superbloque . Ambos son parte del sistema de archivos en lugar de la partición. Por ejemplo, ext2–4 contienen un UUID, mientras que NTFS o FAT32 no. El superbloque es parte del sistema de archivos, por lo tanto está completamente contenido dentro de la partición, por lo que hacer dd if=/dev/sda1 of=/dev/sdb1
deja tanto a sda1 como a sdb1 con la misma etiqueta y UUID.
Existen varios tipos de GUID utilizados en el Modelo de objetos componentes (COM) de Microsoft:
[HKEY_CLASSES_ROOT\Interface]
[30] )[HKEY_CLASSES_ROOT\CLSID]
)[HKEY_CLASSES_ROOT\TypeLib]
[31] )[HKEY_CLASSES_ROOT\Component Categories]
[32] )Los UUID se utilizan comúnmente como una clave única en las tablas de bases de datos . La función NEWID en Microsoft SQL Server versión 4 Transact-SQL devuelve UUID aleatorios estándar de la versión 4, mientras que la función NEWSEQUENTIALID devuelve identificadores de 128 bits similares a los UUID que se comprometen a ascender en secuencia hasta el siguiente reinicio del sistema. [33] La función SYS_GUID de Oracle Database no devuelve un GUID estándar, a pesar del nombre. En su lugar, devuelve un valor RAW de 16 bytes y 128 bits basado en un identificador de host y un identificador de proceso o subproceso, algo similar a un GUID. [34] PostgreSQL contiene un tipo de datos UUID [35] y puede generar la mayoría de las versiones de UUID mediante el uso de funciones de módulos. [36] [37] MySQL proporciona una función UUID , que genera UUID estándar de la versión 1. [38]
La naturaleza aleatoria de los UUID estándar de las versiones 3, 4 y 5, y el orden de los campos dentro de las versiones estándar 1 y 2 pueden crear problemas con la localidad o el rendimiento de la base de datos cuando los UUID se utilizan como claves principales . Por ejemplo, en 2002, Jimmy Nilsson informó de una mejora significativa en el rendimiento con Microsoft SQL Server cuando los UUID de la versión 4 que se utilizaban como claves se modificaron para incluir un sufijo no aleatorio basado en la hora del sistema. Este enfoque denominado "COMB" (GUID de tiempo combinado) hizo que los UUID tuvieran una probabilidad significativamente mayor de duplicarse, como reconoció Nilsson, pero Nilsson solo exigía unicidad dentro de la aplicación. [39] Al reordenar y codificar los UUID de la versión 1 y 2 de modo que la marca de tiempo aparezca primero, se puede evitar la pérdida de rendimiento de inserción. [40]
Las disposiciones de tipo COMB de cargas útiles UUID finalmente se estandarizaron en RFC 9562 como UUIDv6 y UUIDv7.
Se hace referencia a una interfaz en tiempo de ejecución con un identificador de interfaz único global (
IID
). Este
IID
, que es una instancia específica de un identificador único global (
GUID
) compatible con COM, permite que un cliente pregunte a un objeto con precisión si admite la semántica de la interfaz, sin sobrecarga innecesaria y sin la confusión que podría surgir en un sistema al tener múltiples versiones de la misma interfaz con el mismo nombre.
Se almacena una lista de los CATID y los nombres legibles por humanos en una ubicación conocida en el registro.