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。