uniqid unico numero generar genera como uuid

unico - Generando UUID v5. ¿Qué es nombre y espacio de nombres?



uuid javascript (3)

El nombre y el espacio de nombres se pueden usar para crear una jerarquía de UUID únicos (muy probablemente).

En términos generales, un UUID tipo 3 o tipo 5 se genera al mezclar un identificador de espacio de nombres con un nombre. Los UUID tipo 3 usan MD5 y los UUID tipo 5 usan SHA1. Solo 128 bits están disponibles y 5 bits se usan para especificar el tipo, por lo que todos los bits de hash no llegan al UUID. (También MD5 se considera criptográficamente roto, y SHA1 está en sus últimas etapas, así que no lo use para verificar los datos que deben ser "muy seguros"). Dicho esto, le proporciona una forma de crear una función "hash" repetible / verificable que asigna un nombre posiblemente jerárquico a un valor probabilísticamente único de 128 bits, que puede actuar como un hash jerárquico o MAC.

Supongamos que tiene un almacén (clave, valor), pero solo admite un espacio de nombres. Puede generar un gran número 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 tipo 1 (host + marca de tiempo) o tipo 4 (aleatorio), siempre y cuando lo guarde en algún lugar. Alternativamente, puede crear un UUID aleatorio para su raíz (o usar el UUID null : 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 lanzar en un único almacén de valor-clave con una alta probabilidad de evitar la colisión. Este proceso se puede repetir recursivamente, de modo que si, por ejemplo, el "valor" asociado con una clave UUID a su vez representa algún tipo de "espacio de nombres" lógico como un cubo, contenedor o directorio, su UUID se puede usar a su vez para generar más jerárquicos UUIDs.

El UUID de tipo 3 o 5 generado genera un hash (parcial) del ID de espacio de nombres y del espacio de nombres de nombres (clave). No contiene más el UUID del espacio de nombres que un mensaje MAC que contiene el contenido del mensaje del que está codificado. El nombre es una cadena "arbitraria" (octeto) desde la perspectiva del algoritmo uuid. Su significado sin embargo depende de su aplicación. Podría ser un nombre de archivo dentro de un directorio lógico, id de objeto dentro de un almacén de objetos, etc.

Si bien esto funciona bien para una cantidad moderadamente grande de espacios de nombres y claves, eventualmente se desvanece si apuntas a una gran cantidad de claves que son únicas con una probabilidad muy alta. La entrada de Wikipedia para el problema de cumpleaños (también conocida como la paradoja de cumpleaños) incluye una tabla que ofrece las probabilidades de al menos una colisión para varios números de llaves y tamaños de tabla. Para 128 bits, el hash 26 mil millones de claves de esta manera tiene una probabilidad de colisión de p=10^-18 (despreciable), pero 26 trillones de claves, aumenta la probabilidad de al menos una colisión a p=10^-12 (uno en un billón), y el hashing de 26*10^15 teclas, aumenta la probabilidad de al menos una colisión a p=10^-6 (una en un millón). Al ajustarse a 5 bits que codifican el tipo UUID, se agotará un poco más rápido, por lo que un billón de claves tiene aproximadamente una probabilidad de 1 en un billón de tener una sola colisión.

Ver http://en.wikipedia.org/wiki/Birthday_problem#Probability_table para la tabla de probabilidad.

Consulte http://www.ietf.org/rfc/rfc4122.txt para obtener más detalles sobre las codificaciones UUID.

He leído la página del man , pero no comprendo para qué sirve el name y el namespace .

Para los UUID de la versión 3 y la versión 5, se deben proporcionar los argumentos de línea de comando adicionales, el espacio de nombres y el nombre. El espacio de nombres es un UUID en representación de cadena o un identificador para UUID de espacio de nombres predefinidos internamente (actualmente conocidos son "ns: DNS", "ns: URL", "ns: OID" y "ns: X500"). El nombre es una cadena de longitud arbitraria.

El espacio de nombres:

El espacio de nombres es un UUID en representación de cadena o un

¿Significa que necesito almacenarlo (UUID v4) en algún lugar en relación con el UUID v5 generado? En cualquier caso, ¿por qué no se hace esto automáticamente?

El nombre es una cadena de longitud arbitraria.

name una cadena completamente aleatoria? ¿Cuál es el propósito de esto entonces? ¿Se puede decodificar desde el UUID v5?


Los UUID tipo 3 y tipo 5 son solo una técnica para rellenar un hash en un UUID.

  • Tipo 1: rellena la dirección MAC, datetime en 128 bits
  • Tipo 3 : rellena un hash MD5 en 128 bits
  • Tipo 4: mete datos aleatorios en 128 bits
  • Tipo 5 : rellena un hash SHA1 en 128 bits

Un hash SHA1 genera 160 bits (20 bytes). El resultado del hash se convierte en un UUID. De los 20 bytes de SHA1:

SHA1 Digest: 74738ff5 5367 e958 9aee 98fffdcd1876 94028007 UUID (v5): 74738ff5-5367-5958-9aee-98fffdcd1876 ^_low nibble is set to 5 to indicate type 5 ^_first two bits set to 1 and 0, respectively

(Tenga en cuenta que los dos primeros bits de ''9'' ya son 1 y 0, respectivamente, por lo que esto no tiene efecto).

¿Qué hago?

Probablemente te estés preguntando qué es lo que se supone que debo hacer. Básicamente hash la concatenación de:

sha1([NamespaceUUID]+[AnyString]);

Prefieres tu cadena con un llamado espacio de nombres para evitar conflictos de nombres.

El UUID RFC predefinirá 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 juntarse:

DnsUUID = sha1(Namespace_DNS + ".com"); UrlUUID = sha1(Namespace_URL + ".com");

El RFC entonces define cómo:

  • tomar los 160 bits de SHA1
  • y convertirlo en 128 bits de un UUID

La idea básica es tomar solo los primeros 128 bits, rellenar un 5 en el registro de tipo y luego establecer los dos primeros bits de la sección clock_seq_hi_and_reserved 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 pseudo-código):

UUID NameToUUID(UUID NamespaceUUID, String Name) { byte[] hash = sha1(NamespaceUUID.ToBytes() + Name.ToBytes()); UUID result; Copy(hash, result, 16); result[6] &= 0x0F; result[6] |= 0x50; result[8] &= 0x3F; result[8] |= 0x80; return result; }

(Tenga en cuenta que la endiancia de su sistema puede afectar los índices de los bytes anteriores)

Puedes tener llamadas:

uuid = NameToUUID(Namespace_DNS, ''www..com''); uuid = NameToUUID(Namespace_DNS, ''www.google.com''); uuid = NameToUUID(Namespace_URL, ''http://www..com''); uuid = NameToUUID(Namespace_URL, ''http://www.google.com/search&q=rfc+4112''); uuid = NameToUUID(Namespace_URL, ''http://.com/questions/5515880/test-vectors-for-uuid-version-5-converting-hash-into-guid-algorithm'');

Ahora volvamos a tu pregunta

Para los UUID de la versión 3 y la versión 5, se deben proporcionar los argumentos de línea de comando adicionales, el espacio de nombres y el nombre. El espacio de nombres es un UUID en representación de cadena o un identificador para UUID de espacio de nombres predefinidos internamente (actualmente conocidos son "ns: DNS", "ns: URL", "ns: OID" y "ns: X500"). El nombre es una cadena de longitud arbitraria.

El espacio de nombres es cualquier UUID que te guste. Puede ser uno de los predefinidos, o puede inventarlo usted mismo, por ejemplo:

UUID Namespace_RectalForeignExtractedObject = ''4d79546f-6e67-7565-496e-486572417373''

El nombre es una cadena de longitud arbitraria.

El nombre es solo el texto que desea que se agregue al espacio de nombres, luego se marque y se rellene en un UUID:

uuid = NameToUUID(''8e884ace-bee4-11e4-8dfc-aa07a5b093db'', ''screwdriver''); uuid = NameToUUID(''8e884ace-bee4-11e4-8dfc-aa07a5b093db'', ''toothbrush''); uuid = NameToUUID(''8e884ace-bee4-11e4-8dfc-aa07a5b093db'', ''broomstick''); uuid = NameToUUID(''8e884ace-bee4-11e4-8dfc-aa07a5b093db'', ''orange''); uuid = NameToUUID(''8e884ace-bee4-11e4-8dfc-aa07a5b093db'', ''axe handle''); uuid = NameToUUID(''8e884ace-bee4-11e4-8dfc-aa07a5b093db'', ''impulse body spray''); uuid = NameToUUID(''8e884ace-bee4-11e4-8dfc-aa07a5b093db'', ''iPod Touch'');

Nota : Cualquier código liberado en dominio público. No se requiere atribución.


Un nombre no es más que un identificador que es único dentro de un espacio de nombres. El problema es que los espacios de nombres suelen ser bastante pequeños y los nombres en uno a menudo chocan con los nombres en 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; otros DMV estatales pueden haber usado el mismo nombre en sus propios espacios de nombres. Heck, alguien más puede tener un número de teléfono (nombre) que también coincide porque es otro espacio de nombres, etc.

Se puede considerar que los UUID habitan en un solo espacio de nombres tan vasto que puede proporcionar un nombre único para todo ; eso es lo que significa "universal". Pero, ¿cómo asigna los nombres existentes en otros espacios de nombres a un UUID?

Una solución obvia es generar un UUID (V1 o V4) para que cada elemento reemplace los nombres antiguos en sus espacios de nombres separados. El inconveniente 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 completamente de los nombres antiguos. de todos modos, lo que significa que ahora cada elemento tiene dos nombres, ¿así que mejoraste o empeoraste las cosas?

Aquí es donde entra V3 / V5. Los UUID se ven tan aleatorios como V4 pero en realidad son deterministas; cualquier persona que tenga el UUID correcto para un espacio de nombres puede generar independientemente el mismo UUID para cualquier nombre dado dentro de ese espacio de nombres. No necesita publicarlos en absoluto, ni siquiera generarlos previamente, ¡ya que cualquiera puede crearlos sobre la marcha según sea necesario!

Los nombres de DNS y las URL son espacios de nombres muy comúnmente utilizados, por lo que se publicaron UUID estándar para ellos; Los nombres de ASN.1 OID y X.500 no son tan comunes, pero a los organismos de estándares les encantan, 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 quien 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: crea un UUID "base" (de cualquier tipo) y luego lo usa como espacio de nombres para nombrar sus otros espacios de nombres. De esa manera, solo tienes que publicar el UUID base (o usar uno obvio), y todos pueden calcular el resto.

Por ejemplo, quedémonos, queríamos crear algunos UUID para ; que tiene un nombre obvio dentro del espacio de nombres DNS, por lo que la base es obvia:

uuid ns_dns = ''6ba7b810-9dad-11d1-80b4-00c04fd430c8''; uuid ns_base = uuidv5(ns_dns, ''.com'');

tiene espacios de nombres separados para los usuarios, preguntas, respuestas, comentarios, etc., pero también son bastante obvios:

uuid ns_user = uuidv5(ns_base, ''user''); uuid ns_question = uuidv5(ns_base, ''question''); uuid ns_answer = uuidv5(ns_base, ''answer''); uuid ns_comment = uuidv5(ns_base, ''comment'');

Esta pregunta en particular es # 10867405, por lo que su UUID sería:

uuid here = uuidv5(ns_question, ''10867405'');

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 colisionará con un UUID generado a partir de cualquier otro par de espacio de nombres / nombres.