python3标识符_Python3标准库:uuid 全局唯一标识符

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地址,并且可能返回其中任意一个值。

b_0_202004141600587192.png

要为一个主机(由其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。

b_0_202004141601016133.png

由于有时间分量(time),所以每次调用uuid1()都会返回一个新值。

import uuid

for i in range(3):

print(uuid.uuid1())

在这个输出中,只有时间分量(串的开始部分)有变化。

b_0_202004141601011618.jpg

由于每个计算机有不同的mac地址,所以在不同系统上运行这个示例程序会生成完全不同的值。下一个例子传递不同的节点id来模拟在不同主机上运行。

import uuid

for node in [0x1ec200d9e0, 0x1e5274040e]:

print(uuid.uuid1(node), hex(node))

除了返回不同的时间值,uuid末尾的节点标识符也有变化。

b_0_202004141601014346.jpg

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()。

b_0_202004141601015602.jpg

不论什么时间计算或者在哪里计算,一个命名空间中给定名的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值则是不同的。

b_0_202004141601059715.jpg

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模块。

b_0_202004141601055171.jpg

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值。

b_0_202004141601053101.jpg

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值