Python—UUID


Python—UUID(通用唯一识别码)

一、UUID简介

​ UUID(Universally Unique IDentifier)是128位的全局唯一标识符,通常由32字节的字符串表示。按照官方手册的说法可以”在空间和时间上保证唯一性”。 它通过MAC地址、时间戳、命名空间、随机数、伪随机数来保证生成ID的唯一性。

二、UUID的五种算法

1、UUID 1 - IEEE 802 MAC Address

​ UUID的第一个版本的值是基于主机的 MAC 地址、当前时间戳、随机数来计算的。uuid 模块使用 getnode() 来获取当前系统的 MAC 地址值。如果一个系统的网卡多于一块,那么就有多个 MAC 地址,因此返回的值可能是其中的任意一个。

>>> import uuid
>>> uuid.getnode()
52239257997

​ 要为主机生成一个由它的 MAC 地址标明的 UUID ,那么就使用 uuid1() 函数。节点标识参数不是必须的,如果留空就意味着采用 getnode() 返回的值,但是因为UUID中包含时间戳,所以每次运行都会生成一个不同的值。

>>> import uuid
>>> uuid.uuid1()
UUID('ec5d1cf8-7b20-11ea-b8b2-c85b76bbedeb')
>>> uuid.uuid1()
UUID('1a9964be-7b21-11ea-b8b2-c85b76bbedeb')

​ 但是在新的输出中,仅仅只有时间组成部分(在字符串开头位置)有改变,后面是一样的,所以该方式是有风险的,在局域网中可以使用IP来代替MAC,也可以指定 node 值来创建新值。

>>> for node in [0x1ec200d9e0, 0x1e5274040e]:
...     print(uuid.uuid1(node), hex(node), type(node))
...
f6f9a2ba-7b22-11ea-83f4-001ec200d9e0 0x1ec200d9e0 <class 'int'>
f6f9af42-7b22-11ea-acc2-001e5274040e 0x1e5274040e <class 'int'>

2、UUID 2 - 基于分布式计算环境DCE

​ 算法和uuid1相同,不同的是把时间戳的前4位换位POSIX的UID,实际中很少用到该方法,因此Python中没有这个函数,故忽略。

3、UUID 3 - 基于名字和MD5散列值

​ 通过计算名字和命名空间的MD5散列值得到,保证了同一命名空间中不同名字的唯一性,和不同命名空间的唯一性,但同一命名空间的名字生成相同的uuid。将名称空间的特定种子值与名称组合在一起。这有几个众所周知的命名空间,由预定义的 UUID 值标识,用于处理 DNS,URLs, ISO OIDs, 以及 X.500 可分辨名称。可以通过生成和存储 UUID 值来定义新的基于应用的命名空间.

import uuid
>>> print('  MD5   :', uuid.uuid3(uuid.NAMESPACE_DNS, 'valecasec.github.io'))
  MD5   : 1037d0d1-41f2-3e43-9e32-77649b28efe7

>>> print('  MD5   :', uuid.uuid3(uuid.NAMESPACE_URL, 'valecasec.github.io'))
  MD5   : 87118883-8681-3357-8de8-a9d81c9ca89b

>>> print('  MD5   :', uuid.uuid3(uuid.NAMESPACE_OID, 'valecasec.github.io'))
  MD5   : 2beb716c-3841-329e-b29d-30ae925488bb

>>> print('  MD5   :', uuid.uuid3(uuid.NAMESPACE_X500, 'valecasec.github.io'))
  MD5   : 8182d37a-e93b-36c8-a378-aa233ef06459

4、UUID 4 - 基于随机值

​ 当基于名称和命名的 UUID 值不够,并且为了更好的避免哈希碰撞时,引入伪随机数,但是由于有一定的重复概率,这个概率又可以被计算出来,所以该种方法也不够安全。

import uuid
>>> for i in range(3):
...     print(uuid.uuid4(), i)
...
4a2e2a2a-318b-4bb4-be79-c749c3239704 0
342f19a9-79e7-4974-90f4-e168b54fea20 1
eddd6eba-64b6-4cd1-ae12-30d682252614 2

​ 随机源取决于 uuid 被导入时可用的 C 库。如果 libuuid 或者 (uuid.dll)能够被加载,将使用库中包含生成随机值的函数。否则使用 os.urandom() 或者使用 random 模块。

5、UUID 5 - 基于名字和SHA1散列值

​ 算法和uuid3()相同,不同的是使用Secure Hash Algorithm 1 算法。

import uuid
>>> print('  SHA1   :', uuid.uuid5(uuid.NAMESPACE_DNS, 'valecasec.github.io'))
  SHA1   : 770551b4-31a3-5867-85a7-a95a5343a58c

>>> print('  SHA1   :', uuid.uuid5(uuid.NAMESPACE_URL, 'valecasec.github.io'))
  SHA1   : 4cd268ba-fac0-5cdf-a63f-3732efe8eb77

>>> print('  SHA1   :', uuid.uuid5(uuid.NAMESPACE_OID, 'valecasec.github.io'))
  SHA1   : d753ca93-d925-5465-9b2b-1679f60d46df

>>> print('  SHA1   :', uuid.uuid5(uuid.NAMESPACE_X500, 'valecasec.github.io'))
  SHA1   : b22bedee-2d2e-5142-9b65-4d91a487bad1

三、使用推荐

  • 如果在global的分布式计算环境下,最好用uuid1
  • 由于uuid4存在概率性重复,可以分场合使用
  • 如果有名字的唯一性要求,最好使用uuid3或uuid5

虽然Python可以很方便的生成UUID,但是在这里还是要推荐一个网址,可以在线生成UUID:

http://www.uuid.online

文章作者: valecalida
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 valecalida !
评论
  目录