PyMOTW: uuid
4 Agosto 2008
Traducción de PyMOTW:
uuid el módulo
uuid de la columna semanal de Doug Hellmann.
El módulo uuid implementa Identificadores Universalmente Únicos (Universally
Unique Identifiers) como se describen en el RFC
4122.
| Módulo: | uuid |
|---|---|
| Propósito: | Generar identificadores únicos para objetos. |
| Versión de Python: | 2.5 |
Descripción:
RFC 4122 define un sistema para crear identificadores universalmente únicos para recursos de una manera que no requiere un registro central. Valores UUID son de 128 bits y "pueden garantizar singularidad a través del espacio y el tiempo". Son útiles para identificadores de documentos, hosts, clientes de aplicaciones y otras situaciones donde un valor único es necesario. El RFC está orientada específicamente a crear un espacio de nombres uniformes de recursos (Uniform Resource Name namespace).
Tres algoritmos principales son descritos en la especificación:
- Usando direcciones MAC IEEE 802 como una fuente de singularidad
- Usando número pseudo al azar
- Usando cadenas conocidas combinadas con sumas criptográficas
En todos los casos, el valor semilla se combina con el reloj del sistema y un valor de secuencia del reloj (para mantener singularidad en caso que el reloj haya sido retrasado).
UUID 1 - Dirección MAC IEEE 802:
Valores UUID versión 1 se calculan usando la dirección MAC del host. El
módulo uuidusa getnode() para extraer el valor MAC en un sistema:
import uuid
print hex(uuid.getnode())
$ python uuid_getnode.py
0x13a94e3959L
Si un sistema tiene más de una tarjeta de red, y por tanto más de una MAC, cualquiera de los valores puede ser el resultado.
Para generar el UUID de una tarjeta de red dada, identificada por su dirección
MAC, usa la función uuid1(). Puedes pasarle un identificador de nodo o dejar
el campo vacío para usar el valor devuelto por getnode().
import uuid
u = uuid.uuid1()
print u
print type(u)
print 'bytes :', repr(u.bytes)
print 'hex :', u.hex
print 'int :', u.int
print 'urn :', u.urn
print 'variant :', u.variant
print 'version :', u.version
print 'fields :', u.fields
print '\ttime_low : ', u.time_low
print '\ttime_mid : ', u.time_mid
print '\ttime_hi_version : ', u.time_hi_version
print '\tclock_seq_hi_variant: ', u.clock_seq_hi_variant
print '\tclock_seq_low : ', u.clock_seq_low
print '\tnode : ', u.node
print '\ttime : ', u.time
print '\tclock_seq : ', u.clock_seq
Los componentes del objeto UUID devuelto son accesible a través de atributos de instancia sólo de lectura. Algunos atributos, como hex, int y urn, son representaciones distintas del valor UUID.
$ python uuid_uuid1.py
56a638a0-6298-11dd-9170-0013a94e3959
<class 'uuid.UUID'>
bytes : 'V\xa68\xa0b\x98\x11\xdd\x91p\x00\x13\xa9N9Y'
hex : 56a638a0629811dd91700013a94e3959
int : 115176677437976725286414991448563661145
urn : urn:uuid:56a638a0-6298-11dd-9170-0013a94e3959
variant : specified in RFC 4122
version : 1
fields : (1453734048L, 25240L, 4573L, 145L, 112L, 84444854617L)
time_low : 1453734048
time_mid : 25240
time_hi_version : 4573
clock_seq_hi_variant: 145
clock_seq_low : 112
node : 84444854617
time : 134371970319268000
clock_seq : 4464
Debido al componente time, cada vez que se invoca uuid1() un nuevo valor es
devuelto.
import uuid
for i in xrange(3):
print uuid.uuid1()
Nota en este resultado que solamente el componente de tiempo (al inicio de la cadena) cambia.
$ python uuid_uuid1_repeat.py
a9a0122e-6298-11dd-a0e0-0013a94e3959
a9a01846-6298-11dd-a0e0-0013a94e3959
a9a01a80-6298-11dd-a0e0-0013a94e3959
Por supuesto, ya que tu computadora tiene una dirección MAC distinta a la mía, verás valores enteramente distintos si ejecutas los ejemplos, porque e identificador de nodo al final del UUID cambiará también.
import uuid
node1 = uuid.getnode()
print hex(node1), uuid.uuid1(node1)
node2 = 0x1e5274040e
print hex(node2), uuid.uuid1(node2)
$ python uuid_uuid1_othermac.py
0x13a94e3959L f7ab00fa-6298-11dd-8593-0013a94e3959
0x1e5274040eL f7ab05a8-6298-11dd-b475-001e5274040e
UUID 3 y 5 - Valores basados en nombres:
Es también útil en ciertos contextos el crear valores UUID a partir de nombres en lugar de valores al azar o basados en el tiempo Las versiones 3 y 5 de la especificación UUID utilizan sumas criptográficas (MD5 o SHA-1) para combinar valores semilla específicos con "nombres" (nombres DNS, URLs, identificadores de objetos, etc.). Hay muchos espacios de nombres conocidos, identificados por valores UUID pre definidos, para trabajar con DNS, URLs, OIDs de ISO y nombres distinguidos (distinguished names) de X.500. Puedes también definir tu propio espacio de nombres específico a una aplicación generando y guardando valores UUID.
Para crear un UUID desde un nombre DNS, pasa uuid.NAMESPACE_DNS como el
argumento del espacio de nombres del nombre a uuid3() o uuid5():
import uuid
hostnames = ['www.doughellmann.com', 'blog.doughellmann.com']
for name in hostnames:
print name
print '\tMD5 :', uuid.uuid3(uuid.NAMESPACE_DNS, name)
print '\tSHA-1 :', uuid.uuid5(uuid.NAMESPACE_DNS, name)
$ python uuid_uuid3_uuid5.py
www.doughellmann.com
MD5 : bcd02e22-68f0-3046-a512-327cca9def8f
SHA-1 : e3329b12-30b7-57c4-8117-c2cd34a87ce9
blog.doughellmann.com
MD5 : 9bdabfce-dfd6-37ab-8a3f-7f7293bcf111
SHA-1 : fa829736-7ef8-5239-9906-b4775a5abacb
El valor UUID para el mismo nombre es siempre el mismo, sin importar cuándo o dónde es calculado. Valores para el mismo nombre en distintos espacios de nombres son distintos por supuesto.
import uuid
for i in xrange(3):
print uuid.uuid3(uuid.NAMESPACE_DNS, 'www.doughellmann.com')
$ python uuid_uuid3_repeat.py
bcd02e22-68f0-3046-a512-327cca9def8f
bcd02e22-68f0-3046-a512-327cca9def8f
bcd02e22-68f0-3046-a512-327cca9def8f
UUID 4 - Valores al azar:
A veces, valores UUID basados en host o espacios de nombres no son
"suficientemente distintos". E casos donde quieres usar el UUID como una llave
de búsqueda, una secuencia más al azar con más diferenciación es deseable.
Es estas situaciones, usa uuid4() para generar UUIDs desde valores al azar.
import uuid
for i in xrange(3):
print uuid.uuid4()
$ python uuid_uuid4.py
bff4da9f-c7f2-4b1a-a456-4a3e50102dec
7e894f08-e970-456d-8743-e53680adfd7c
b25e24f1-9382-4e68-b820-228c02aae263
Trabajando con objetos UUID:
Además de generar nuevos valores UUID, puedes analizar cadenas en varios formatos para crear objetos UUID. Ésto hace más fácil el compararlos, ordenarlos, etc.
import uuid
def show(msg, l):
print msg
for v in l:
print '\t', v
print
input_values = [
'urn:uuid:f2f84497-b3bf-493a-bba9-7c68e6def80b',
'{417a5ebb-01f7-4ed5-aeac-3d56cd5037b0}',
'2115773a-5bf1-11dd-ab48-001ec200d9e0',
]
show('input_values', input_values)
uuids = [ uuid.UUID(s) for s in input_values ]
show('convertidos en uuids', uuids)
uuids.sort()
show('ordenados', uuids)
$ python uuid_uuid_objects.py
input_values
urn:uuid:f2f84497-b3bf-493a-bba9-7c68e6def80b
{417a5ebb-01f7-4ed5-aeac-3d56cd5037b0}
2115773a-5bf1-11dd-ab48-001ec200d9e0
convertidos en uuids
f2f84497-b3bf-493a-bba9-7c68e6def80b
417a5ebb-01f7-4ed5-aeac-3d56cd5037b0
2115773a-5bf1-11dd-ab48-001ec200d9e0
ordenados
2115773a-5bf1-11dd-ab48-001ec200d9e0
417a5ebb-01f7-4ed5-aeac-3d56cd5037b0
f2f84497-b3bf-493a-bba9-7c68e6def80b
Referencias:
RFC 4122: A Universally Unique IDentifier (UUID) URN Namespace
Python Module of the Week Home
Descarga el código
Copyright 2008 Doug Hellmann
blog comments powered by Disqus
