1. uuid 全域唯一識別符號
uuid 模塊實作了全域唯一識別符號(Universally Unique Identifier);這個RFC定義了一個系統,可以為資源創建唯一的識別符號,這里采用一種不需要集中注冊機的方式,UUID值為128位,正如參考指南所述,“UUID可以保證跨空間和時間的唯一性”,對于檔案、主機、應用客戶以及其他需要唯一值的情況,UUID可以用來生成識別符號,這個RFC特別強調創建一個統一資源名(Uniform Resource Name)命名空間,并且涵蓋了3個主要演算法,
- 使用IEEE802MAC地址作為唯一性來源
- 使用偽亂數
- 使用公開的串并結合密碼散列
在上述所有情況下,種子值都要與系統時鐘結合,如果向后設定時鐘,則要用一個時鐘序列值維護唯一性,
1.1 UUID1: IEEE 802 MAC地址
UUID1值使用主機的MAC地址計算,uuid模塊使用getnode()來獲取當前系統的MAC值,
import uuid print(hex(uuid.getnode()))
如果一個系統有多個網卡,那么相應地便會有多個MAC地址,并且可能回傳其中任意一個值,

要為一個主機(由其MAC地址標識)生成一個UUID,需要使用uuid1()函式,節點識別符號引數是可選的;如果沒有設定這個域,那么便會使用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(' 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物件,可以通過只讀的實體屬性訪問它的各個部分,有些屬性是UUID值的不同表示,如hex、int和urn,

由于有時間分量(time),所以每次呼叫uuid1()都會回傳一個新值,
import uuid for i in range(3): print(uuid.uuid1())
在這個輸出中,只有時間分量(串的開始部分)有變化,

由于每個計算機有不同的MAC地址,所以在不同系統上運行這個示例程式會生成完全不同的值,下一個例子傳遞不同的節點ID來模擬在不同主機上運行,
import uuid for node in [0x1ec200d9e0, 0x1e5274040e]: print(uuid.uuid1(node), hex(node))
除了回傳不同的時間值,UUID末尾的節點識別符號也有變化,

1.2 UUID 3和5 基于名字的值
有些情況下可能需要根據名字創建UUID值,而不是根據隨機值或基于時間的值來創建,UUID3和5規范使用密碼散列值(分別使用MD5或SHA-1),將特定于命名空間的種子值與名字相結合,有一些由預定義UUID值標識的公開的命名空間,分別用于處理DNS、URL、ISO OID和X.500識別名(Distinguished Name),通過生成和保存UUID值,還可以定義新的特定于應用的命名空間,
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()
要從一個DNS名創建UUID,可以把uuid.NAMESPACE_DNS作為命名空間引數傳入uuid3()或uuid5(),

不論什么時間計算或者在哪里計算,一個命名空間中給定名的UUID值總是相同的,
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()
但是命名空間中相同名字的UUID值則是不同的,

1.3 UUID 4 亂數
有時,基于主機和基于命名空間的UUID值“差別還不夠大”,例如,如果UUID要作為散列鍵,則需要有區分度更大、更隨機的值序列來避免散串列中出現沖突,讓值有更少的共同數字也能更容易地在日志檔案中查找這些值,為了增加UUID的區分度,可以使用uuid4()利用隨機的輸入值生成UUID,
import uuid for i in range(3): print(uuid.uuid4())
隨機性的來源取決于匯入uuid時哪些C庫可用,如果可以加載libuuid(或uuid.d11),而且其中包含一個生成隨機值的函式,那么便使用這個函式,否則,使用os.urandom()或random模塊,

1.4 處理UUID物件
除了生成新的UUID值,還可以決議標準格式的串以創建UUID物件,使比較和排序操作的處理更為容易,
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:的前綴,則這個前綴也會被洗掉,剩下的文本必然是由十六進制數構成的串,然后再將它解釋為一個UUID值,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/158894.html
標籤:Python
上一篇:Can I install Python 3.x and 2.x on the same Windows computer?
下一篇:pandas常用API_1
