Автор оригинала: Doug Hellmann.
Цель:
В
uuid
модуль реализует универсальные уникальные идентификаторы, как описано в RFC 4122.
RFC 4122 определяет систему для создания универсальных уникальных идентификаторов для ресурсов таким образом, чтобы не требуется центральный регистратор. Значения UUID имеют длину 128 бит и, как сказано в справочнике, «могут гарантировать уникальность в пространстве и времени». Они полезны для генерации идентификаторов для документов, хостов, клиентов приложений и других ситуаций, когда необходимо уникальное значение. RFC специально ориентирован на создание пространства имен Uniform Resource Name и охватывает три основных алгоритма:
- Использование MAC-адресов IEEE 802 как источника уникальности
- Использование псевдослучайных чисел
- Использование хорошо известных строк в сочетании с криптографическим хешированием
Во всех случаях начальное значение комбинируется с системными часами и значением тактовой последовательности, используемым для поддержания уникальности в случае, если часы установлены в обратном направлении.
UUID 1 – MAC-адрес IEEE 802
Значения UUID версии 1 вычисляются с использованием MAC-адреса хоста. Модуль uuid
использует getnode ()
для получения значения MAC текущей системы.
uuid_getnode.py
import uuid print(hex(uuid.getnode()))
Если в системе более одной сетевой карты и, следовательно, более одного MAC, может быть возвращено любое из значений.
$ python3 uuid_getnode.py 0xa860b60304d5
Чтобы сгенерировать UUID для хоста, идентифицируемого по его MAC-адресу, используйте функцию uuid1 ()
. Аргумент идентификатора узла не является обязательным; оставьте поле пустым, чтобы использовать значение, возвращаемое getnode ()
.
uuid_uuid1.py
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(' time_low : ', u.time_low) print(' time_mid : ', u.time_mid) print(' time_hi_version : ', u.time_hi_version) print(' clock_seq_hi_variant: ', u.clock_seq_hi_variant) print(' clock_seq_low : ', u.clock_seq_low) print(' node : ', u.node) print(' time : ', u.time) print(' clock_seq : ', u.clock_seq)
К компонентам возвращенного объекта UUID можно получить доступ через атрибуты экземпляра только для чтения. Некоторые атрибуты, такие как hex
, int
и urn
, представляют собой разные представления значения UUID.
$ python3 uuid_uuid1.py 38332b62-2aea-11e8-b103-a860b60304d5bytes : b'83+b*\xea\x11\xe8\xb1\x03\xa8`\xb6\x03\x04\xd5' hex : 38332b622aea11e8b103a860b60304d5 int : 74702454824994792138317938288475964629 urn : urn:uuid:38332b62-2aea-11e8-b103-a860b60304d5 variant : specified in RFC 4122 version : 1 fields : (942877538, 10986, 4584, 177, 3, 185133323977941) time_low : 942877538 time_mid : 10986 time_hi_version : 4584 clock_seq_hi_variant: 177 clock_seq_low : 3 node : 185133323977941 time : 137406974088391522 clock_seq : 12547
Из-за компонента времени каждый вызов uuid1 ()
возвращает новое значение.
uuid_uuid1_repeat.py
import uuid for i in range(3): print(uuid.uuid1())
В этом выводе изменяется только компонент времени (в начале строки).
$ python3 uuid_uuid1_repeat.py 3842ca28-2aea-11e8-8fec-a860b60304d5 3844cd18-2aea-11e8-aca3-a860b60304d5 3844cdf4-2aea-11e8-ac38-a860b60304d5
Поскольку каждый компьютер имеет свой MAC-адрес, запуск программы-примера в разных системах даст совершенно разные значения. В этом примере передаются явные идентификаторы узлов для имитации работы на разных хостах.
uuid_uuid1_othermac.py
import uuid for node in [0x1ec200d9e0, 0x1e5274040e]: print(uuid.uuid1(node), hex(node))
В дополнение к другому значению времени также изменяется идентификатор узла в конце UUID.
$ python3 uuid_uuid1_othermac.py 3851ea50-2aea-11e8-936d-001ec200d9e0 0x1ec200d9e0 3852caa6-2aea-11e8-a805-001e5274040e 0x1e5274040e
UUID 3 и 5 – значения на основе имени
В некоторых контекстах также полезно создавать значения UUID из имен вместо случайных или основанных на времени значений. Версии 3 и 5 спецификации UUID используют криптографические хеш-значения (MD5 или SHA-1, соответственно) для объединения начальных значений, зависящих от пространства имен, с именами. Существует несколько хорошо известных пространств имен, определяемых заранее заданными значениями UUID, для работы с DNS, URL-адресами, ISO OID и отличительными именами X.500. Новые пространства имен для конкретных приложений могут быть определены путем создания и сохранения значений UUID.
uuid_uuid3_uuid5.py
import uuid hostnames ['www.doughellmann.com', 'blog.doughellmann.com'] for name in hostnames: print(name) print(' MD5 :', uuid.uuid3(uuid.NAMESPACE_DNS, name)) print(' SHA-1 :', uuid.uuid5(uuid.NAMESPACE_DNS, name)) print()
Чтобы создать UUID из имени DNS, передайте uuid.NAMESPACE_DNS
в качестве аргумента пространства имен в uuid3 ()
или uuid5 ()
:
$ python3 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
Значение UUID для данного имени в пространстве имен всегда одно и то же, независимо от того, когда и где оно вычислено.
uuid_uuid3_repeat.py
import uuid namespace_types sorted( n for n in dir(uuid) if n.startswith('NAMESPACE_') ) name 'www.doughellmann.com' for namespace_type in namespace_types: print(namespace_type) namespace_uuid getattr(uuid, namespace_type) print(' ', uuid.uuid3(namespace_uuid, name)) print(' ', uuid.uuid3(namespace_uuid, name)) print()
Значения для одного и того же имени в пространствах имен различаются.
$ python3 uuid_uuid3_repeat.py NAMESPACE_DNS bcd02e22-68f0-3046-a512-327cca9def8f bcd02e22-68f0-3046-a512-327cca9def8f NAMESPACE_OID e7043ac1-4382-3c45-8271-d5c083e41723 e7043ac1-4382-3c45-8271-d5c083e41723 NAMESPACE_URL 5d0fdaa9-eafd-365e-b4d7-652500dd1208 5d0fdaa9-eafd-365e-b4d7-652500dd1208 NAMESPACE_X500 4a54d6e7-ce68-37fb-b0ba-09acc87cabb7 4a54d6e7-ce68-37fb-b0ba-09acc87cabb7
UUID 4 – случайные значения
Иногда значения UUID на основе хоста и пространства имен недостаточно различаются. Например, в случаях, когда UUID предназначен для использования в качестве хеш-ключа, желательна более случайная последовательность значений с большей дифференциацией, чтобы избежать коллизий в хеш-таблице. Наличие значений с меньшим количеством общих цифр также упрощает их поиск в файлах журнала. Чтобы добавить большую дифференциацию в UUID, используйте uuid4 ()
для их генерации с использованием случайных входных значений.
uuid_uuid4.py
import uuid for i in range(3): print(uuid.uuid4())
Источник случайности зависит от того, какие библиотеки C доступны при импорте uuid
. Если libuuid
(или uuid.dll
) может быть загружен и он содержит функцию для генерации случайных значений, он используется. В противном случае используются os.urandom ()
или модуль random.
$ python3 uuid_uuid4.py 74695723-65ed-4170-af77-b9f22608535d db199e25-e292-41cd-b488-80a8f99d163a 196750b3-bbb9-488e-b3ec-62ec0e468bbc
Работа с объектами UUID
Помимо создания новых значений UUID, можно анализировать строки в стандартных форматах для создания объектов UUID, что упрощает обработку операций сравнения и сортировки.
uuid_uuid_objects.py
import uuid def show(msg, l): print(msg) for v in l: print(' ', 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('converted to uuids', uuids) uuids.sort() show('sorted', uuids)
Окружающие фигурные скобки удаляются из ввода, как и тире ( -
). Если в строке есть префикс, содержащий urn:
и/или uuid:
, он также удаляется. Остающийся текст должен быть строкой из 16 шестнадцатеричных цифр, которые затем интерпретируются как значение UUID.
$ python3 uuid_uuid_objects.py input_values urn:uuid:f2f84497-b3bf-493a-bba9-7c68e6def80b {417a5ebb-01f7-4ed5-aeac-3d56cd5037b0} 2115773a-5bf1-11dd-ab48-001ec200d9e0 converted to uuids f2f84497-b3bf-493a-bba9-7c68e6def80b 417a5ebb-01f7-4ed5-aeac-3d56cd5037b0 2115773a-5bf1-11dd-ab48-001ec200d9e0 sorted 2115773a-5bf1-11dd-ab48-001ec200d9e0 417a5ebb-01f7-4ed5-aeac-3d56cd5037b0 f2f84497-b3bf-493a-bba9-7c68e6def80b
Смотрите также
- стандартная библиотечная документация для uuid
- Заметки о переносе Python 2 на 3 для uuid
- RFC 4122 – пространство имен URN с универсальным уникальным идентификатором (UUID)