El nombre y el espacio de nombres se pueden usar para crear una jerarquía de (muy probablemente) UUID únicos.
En términos generales, un UUID de tipo 3 o de tipo 5 se genera al combinar un identificador de espacio de nombres con un nombre. Los UUID de tipo 3 usan MD5 y los UUID de tipo 5 usan SHA1. Solo están disponibles 128 bits y se usan 5 bits para especificar el tipo, por lo que todos los bits hash no se incluyen en el UUID. (También MD5 se considera criptográficamente roto, y SHA1 está en sus últimas etapas, así que no use esto para verificar datos que deben ser "muy seguros"). Dicho esto, le brinda una forma de crear una función de "hash" repetible / verificable que mapee un nombre posiblemente jerárquico en un valor probabilísticamente único de 128 bits, actuando potencialmente como un hash jerárquico o MAC.
Suponga que tiene una tienda (clave, valor), pero solo admite un espacio de nombres. Puede generar una gran cantidad de espacios de nombres lógicos distintos utilizando UUID de tipo 3 o tipo 5. Primero, cree un UUID raíz para cada espacio de nombres. Esto podría ser un UUID de tipo 1 (host + marca de tiempo) o de tipo 4 (aleatorio) siempre que lo guarde en algún lugar. Alternativamente, puede crear un UUID aleatorio para su raíz (o usar el null
UUID: 00000000-0000-0000-0000-000000000000
como raíz) y luego crear un UUID reproducible para cada espacio de nombres usando " uuid -v5 $ROOTUUID $NAMESPACENAME
". Ahora puede crear UUID únicos para claves dentro de un espacio de nombres usando "uuid -v5 $NAMESPACEUUID $KEY
". Estos UUID se pueden colocar en un único almacén de valores-clave con una alta probabilidad de evitar colisiones. Este proceso se puede repetir de forma recursiva de modo que si, por ejemplo, el" valor "asociado con una clave UUID representa a su vez algún tipo de" espacio de nombres lógico " "como un depósito, contenedor o directorio, su UUID se puede utilizar a su vez para generar UUID más jerárquicos.
El UUID de tipo 3 o tipo 5 generado contiene un hash (parcial) de la identificación del espacio de nombres y el nombre dentro del espacio de nombres (clave). No contiene el UUID del espacio de nombres más de lo que un mensaje MAC contiene el contenido del mensaje desde el que está codificado. El nombre es una cadena "arbitraria" (octeto) desde la perspectiva del algoritmo uuid. Sin embargo, su significado depende de su aplicación. Podría ser un nombre de archivo dentro de un directorio lógico, un ID de objeto dentro de un almacén de objetos, etcétera.
Si bien esto funciona bien para una cantidad moderadamente grande de espacios de nombres y claves, eventualmente se agota si está apuntando a una gran cantidad de claves que son únicas con una probabilidad muy alta. La entrada de Wikipedia para el problema del cumpleaños (también conocida como la paradoja del cumpleaños) incluye una tabla que da las probabilidades de al menos una colisión para varios números de teclas y tamaños de tabla. Para 128 bits, el hash de 26 mil millones de claves de esta manera tiene una probabilidad de colisión de p=10^-18
(insignificante), pero 26 billones de claves, aumenta la probabilidad de al menos una colisión con p=10^-12
(uno en un billón), y el hash de 26*10^15
claves aumenta la probabilidad de al menos una colisión parap=10^-6
(uno en un millón). Ajustándose a 5 bits que codifican el tipo UUID, se agotará un poco más rápido, por lo que un billón de claves tienen aproximadamente una probabilidad de 1 en un billón de tener una sola colisión.
Consulte http://en.wikipedia.org/wiki/Birthday_problem#Probability_table para ver la tabla de probabilidad.
Consulte http://www.ietf.org/rfc/rfc4122.txt para obtener más detalles sobre las codificaciones UUID.
Los UUID de tipo 3 y tipo 5 son solo una técnica para rellenar un hash en un UUID.
Un hash SHA1 genera 160 bits (20 bytes); el resultado del hash se convierte en un UUID.
Con el hash de 20 bytes de SHA1:
(Tenga en cuenta que los dos primeros bits de '9' ya son 1 y 0, respectivamente, por lo que esto no tiene ningún efecto).
¿Qué hago hash?
Probablemente se esté preguntando qué es lo que se supone que debo hacer. Básicamente, hash la concatenación de:
Prefija su cadena con un espacio de nombres para evitar conflictos de nombres.
El UUID RFC define previamente cuatro espacios de nombres para usted:
NameSpace_DNS
: {6ba7b810-9dad-11d1-80b4-00c04fd430c8}NameSpace_URL
: {6ba7b811-9dad-11d1-80b4-00c04fd430c8}NameSpace_OID
: {6ba7b812-9dad-11d1-80b4-00c04fd430c8}NameSpace_X500
: {6ba7b814-9dad-11d1-80b4-00c04fd430c8}Entonces, podrían hash juntos:
El RFC luego define cómo:
La esencia básica es tomar solo los primeros 128 bits, rellenar a
5
en el registro de tipo y luego establecer los dos primeros bits de laclock_seq_hi_and_reserved
sección en 1 y 0, respectivamente.Más ejemplos
Ahora que tiene una función que genera un llamado Nombre , puede tener la función (en pseudocódigo):
(Tenga en cuenta que la endianidad de su sistema puede afectar los índices de los bytes anteriores)
Puedes tener llamadas:
Ahora volvamos a tu pregunta
El espacio de nombres es el UUID que desee. Puede ser uno de los predefinidos, o puede crear uno propio, por ejemplo:
El nombre es solo el texto que desea agregar al espacio de nombres, luego hash y relleno en un UUID:
fuente
Namespace_RectalForeignExtractedObject
lo haría.Un nombre no es más que un identificador único dentro de algún espacio de nombres. El problema es que los espacios de nombres suelen ser bastante pequeños y los nombres de uno suelen colisionar con los de otros. Por ejemplo, el número de placa de mi automóvil (nombre) es único dentro del espacio de nombres del DMV de mi estado, pero probablemente no sea único en el mundo; Es posible que otros DMV estatales hayan usado el mismo nombre en sus propios espacios de nombres. Diablos, alguien más puede tener un número de teléfono (nombre) que también coincide porque ese es otro espacio de nombres, etc.
Se puede considerar que los UUID habitan un solo espacio de nombres tan vasto que puede proporcionar un nombre único para todo ; eso es lo que significa "universal". Pero, ¿cómo se asignan los nombres existentes en otros espacios de nombres a un UUID?
Una solución obvia es generar un UUID (V1 o V4) para cada elemento para reemplazar los nombres antiguos en sus espacios de nombres separados. La desventaja es que son mucho más grandes, tienes que comunicar todos los nombres nuevos a todos los que tienen una copia de tu conjunto de datos, actualizar todas tus API, etc. Lo más probable es que no puedas deshacerte de los nombres antiguos por completo. de todos modos, lo que significa que ahora cada elemento tiene dos nombres, así que, ¿mejoró o empeoró las cosas?
Aquí es donde entra en juego V3 / V5. Los UUID parecen tan aleatorios como V4, pero en realidad son deterministas; Cualquiera que tenga el UUID correcto para un espacio de nombres puede generar de forma independiente el mismo UUID para cualquier nombre dentro de ese espacio de nombres. No es necesario publicarlos ni siquiera generarlos previamente, ya que cualquiera puede crearlos sobre la marcha según sea necesario.
Los nombres DNS y las URL son espacios de nombres de uso muy común, por lo que se publicaron UUID estándar para ellos; Los OID ASN.1 y los nombres X.500 no son tan comunes, pero los organismos de estándares los adoran, por lo que también publicaron UUID de espacio de nombres estándar para ellos.
Para todos los demás espacios de nombres, debe generar su propio UUID de espacio de nombres (V1 o V4) y comunicarlo a cualquiera que lo necesite. Si tiene varios espacios de nombres, tener que publicar el UUID para cada uno claramente no es lo ideal.
Aquí es donde entra la jerarquía: usted crea un UUID "base" (de cualquier tipo), y luego lo usa como un espacio de nombres para nombrar sus otros espacios de nombres. De esa forma, solo tienes que publicar el UUID base (o usar uno obvio), y todos pueden calcular el resto.
Por ejemplo, quedémonos que queríamos crear algunos UUID para StackOverflow; que tiene un nombre obvio dentro del espacio de nombres DNS, por lo que la base es obvia:
StackOverflow en sí tiene espacios de nombres separados para usuarios, preguntas, respuestas, comentarios, etc., pero esos también son bastante obvios:
Esta pregunta en particular es # 10867405, por lo que su UUID sería:
Tenga en cuenta que no hay nada aleatorio en este proceso, por lo que cualquiera que siga la misma lógica obtendrá la misma respuesta, sin embargo, el espacio de nombres UUID es tan vasto que (efectivamente, dada la seguridad de un hash criptográfico de 122 bits) nunca chocará con un UUID generado a partir de cualquier otro espacio de nombres / par de nombres.
fuente