uuid定义:

UUID是由一组32位数的16进制数字所构成,是故UUID理论上的总数为1632=2128,约等于3.4 x 1038。也就是说若每纳秒产生1兆个UUID,要花100亿年才会将所有UUID用完。

UUID的标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的32个字符。示例:

550e8400-e29b-41d4-a716-446655440000

UUID亦可刻意重复以表示同类。例如说微软的COM中,所有组件皆必须实现出IUnknown接口,方法是产生一个代表IUnknown的UUID。无论是程序试图访问组件中的IUnknown接口,或是实现IUnknown接口的组件,只要IUnknown一被使用,皆会被参考至同一个ID:00000000-0000-0000-C000-000000000046。

随机UUID的重复机率

随机产生的UUID(例如说由java.util.UUID类别产生的)的128个比特中,有122个比特是随机产生,4个比特在此版本('Randomly generated UUID')被使用,还有2个在其变体('Leach-Salz')中被使用。利用生日悖论,可计算出两笔UUID拥有相同值的机率约为

{\displaystyle p(n)\approx 1-e^{-n^{2}/{2\cdot x}}} p(n)\approx 1-e^{{-n^{2}/{2\cdot x}}}

以下是以x=2122计算出n笔GUID后产生碰撞的机率:n机率

68,719,476,736 = 2360.0000000000000004 (4 x 10-16)

2,199,023,255,552 = 2410.0000000000004 (4 x 10-13)

70,368,744,177,664 = 2460.0000000004 (4 x 10-10)

与被陨石击中的机率比较的话,已知一个人每年被陨石击中的机率估计为170亿分之1[1],也就是说机率大约是0.00000000006 (6 x 10-11),等同于在一年内置立数十兆笔GUID并发生一次重复。换句话说,每秒产生10亿笔UUID,100年后只产生一次重复的机率是50%。如果地球上每个人都各有6亿笔GUID,发生一次重复的机率是50%。

产生重复GUID并造成错误的情况非常低,是故大可不必考虑此问题。

机率也与随机数产生器的质量有关。若要避免重复机率提高,必须要使用基于密码学上的假随机数产生器来生成值才行。

uuid模块

如果你想要的只是一个唯一的ID,使用uuid1()或 uuid4()。

注意:

uuid1()可能会危害隐私,因为它会创建一个包含计算机网络地址的UUID。

uuid4()创建一个随机的UUID。

样例>>> import uuid

>>> #根据主机ID和当前时间生成UUID

>>> uuid.uuid1()

UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')

>>> #基于命名空间和一个字符的MD5加密的UUID

>>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')

UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')

>>> #生成一个随机的UUID

>>> uuid.uuid4()

UUID('16fd2706-8baf-433b-82eb-8c7fada847da')

>>> #使用命名空间的UUID和名称的SHA-1散列生成UUID

>>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')

UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')

>>> #从一个十六进制数字(大括号和连字符被忽略)中生成UUID

>>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')

>>> #将UUID转换为标准形式的十六进制数字字符串

>>> str(x)

'00010203-0405-0607-0809-0a0b0c0d0e0f'

>>> #获取UUID的原始16字节

>>> x.bytes

'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\x0b\x0c\r\x0e\x0f'

>>> #从一个16字节的字符串中生成UUID

>>> uuid.UUID(bytes=x.bytes)

UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')

使用方面:

首先,Python中没有基于DCE的,所以uuid2可以忽略;

其次,uuid4存在概率性重复,由无映射性,最好不用;

再次,若在Global的分布式计算环境下,最好用uuid1;

最后,若有名字的唯一性要求,最好用uuid3或uuid5。