uuid – 汎用一意識別子¶
目的: | RFC 4122 準拠の汎用一意識別子を実装する uuid モジュール |
---|---|
利用できるバージョン: | 2.5 以上 |
RFC 4122 はセントラルレジストラを必要としない方法でリソースの汎用一意識別子を作成するためのシステムを定義します。UUID は128ビット長で “空間と時間を交差して一意性を保証することができます” 。UUID はドキュメント、ホスト、アプリケーションクライアントや一意な値が必要な様々な状況において識別子に便利です。具体的に言うと、その RFC は Uniform Resource Name 名前空間を作成することを対象とします。
3つのメインアルゴリズムがその仕様により適用されます。
- 一意性のソースとして IEEE 802 MAC アドレスを使用する
- 疑似乱数を使用する
- 暗号ハッシュで組み合わせてよく知られた文字列を使用する
全てのケースにおいて、その種の値はシステムクロックと(そのクロックが後進的にセットされたときに一意性を維持するために)クロックシーケンスの値を組み合わせます。
UUID 1 - IEEE 802 MAC アドレス¶
UUID バージョン1の値はホストの MAC アドレスを使用して算出されます。 uuid モジュールはシステムから MAC アドレスを取得するために getnode() を使用します。
import uuid
print hex(uuid.getnode())
$ python uuid_getnode.py
0x70cd60f2c980
もしシステムが1つ以上のネットワークカードを持ち、1つ以上の MAC アドレスがあるなら、その値のどれか1つが返されます。
ホストの UUID を生成するには、その MAC アドレスで識別される 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 '\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
返される UUID オブジェクトのコンポーネントは読み込み専用インスタンス属性を経由してアクセスされます。 hex, int や urn のような属性は UUID の別の表現方法です。
$ python uuid_uuid1.py
eb118663-791f-11e2-a2c4-70cd60f2c980
<class 'uuid.UUID'>
bytes : '\xeb\x11\x86cy\x1f\x11\xe2\xa2\xc4p\xcd`\xf2\xc9\x80'
hex : eb118663791f11e2a2c470cd60f2c980
int : 312459573780010547787799707915419568512
urn : urn:uuid:eb118663-791f-11e2-a2c4-70cd60f2c980
variant : specified in RFC 4122
version : 1
fields : (3943794275L, 31007L, 4578L, 162L, 196L, 124027397130624L)
time_low : 3943794275
time_mid : 31007
time_hi_version : 4578
clock_seq_hi_variant: 162
clock_seq_low : 196
node : 124027397130624
time : 135804116769277539
clock_seq : 8900
時間コンポーネントにより uuid1() が呼び出される毎に新しい値が返されます。
import uuid
for i in xrange(3):
print uuid.uuid1()
(文字列の最初の方にある)時間コンポーネントのみが変更されるこの出力に注意してください。
$ python uuid_uuid1_repeat.py
eb17eba6-791f-11e2-998f-70cd60f2c980
eb190bdc-791f-11e2-80f7-70cd60f2c980
eb190d26-791f-11e2-bb86-70cd60f2c980
あなたのコンピュータは私のものとは違う MAC アドレスを持っているので、そのサンプルをあなたが実行すると全く違う値が表示されます。UUID の最後にあるノード識別子も同様に変更されるでしょう。
import uuid
node1 = uuid.getnode()
print hex(node1), uuid.uuid1(node1)
node2 = 0x1e5274040e
print hex(node2), uuid.uuid1(node2)
$ python uuid_uuid1_othermac.py
0x70cd60f2c980 eb1f026b-791f-11e2-b4c6-70cd60f2c980
0x1e5274040e eb1f6d23-791f-11e2-bdc6-001e5274040e
UUID 3 と 5 - 名前ベースの値¶
乱数や時間ベースの値の代わりに名前から UUID を作成するためのコンテキストも便利です。UUID 仕様のバージョン3と5は “名前” (DNS ホスト名, URL, オブジェクト id 等) と名前空間特有の種の値を組み合わせるために暗号ハッシュ値(MD5 または SHA-1)を使用します。あらかじめ定義された UUID の値により識別される、DNS, URL, ISO OID や X.500 Distinguished Names と連携するよく知られた名前空間があります。
DNS 名から UUID を作成するには、 uuid3() または uuid5() の名前空間引数として uuid.NAMESPACE_DNS を渡してください。
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
名前空間で与えられた名前の UUID の値は、いつ、どこで算出されたとしても常に同じです。異なる名前空間による同じ名前の値は違います。
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 - ランダムな値¶
ホストベースや名前空間ベースの UUID の値は “全然違うものではない” ときがあります。例えば、ある探索キーとして UUID を使用したい状況では、ハッシュテーブルの衝突を避けるためにランダムな値のシーケンスに違いがあるほど望ましいです。また少数の汎用ダイジェストで値を持つこともログファイルではその値を見つけ易くなります。UUID に全然違う値を追加するには、ランダムな入力値を使用して生成する uuid4() を使用してください。
import uuid
for i in xrange(3):
print uuid.uuid4()
$ python uuid_uuid4.py
41ddd08a-383c-49d4-8491-6d66bb41e6a1
c5b0018e-efab-47ed-b1c4-ec100b334a1d
989a52b9-d2c0-415a-af6f-e412c0e31f33
UUID オブジェクトと連携する¶
新たな UUID を生成することに加えて、UUID オブジェクトを作成するために様々なフォーマットの文字列を構文解析することができます。そうすることで対象の値の比較やソートが簡単になります。
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('converted to uuids', uuids)
uuids.sort()
show('sorted', 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
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