python standard library uuid

python 标准库 之 uuid

何谓UUID

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
UUID是128位的全局唯一标识符,通常由32字节的字符串表示。
它可以保证时间和空间的唯一性,也称为GUID,全称为:
UUID —— Universally Unique IDentifier Python 中叫 UUID
UUID -- java.util.UUID Java 中也叫 UUID
GUID —— Globally Unique IDentifier C# 中叫 GUID


它通过MAC地址、时间戳、命名空间、随机数、伪随机数来保证生成ID的唯一性。
UUID主要有五个算法,也就是五种方法来实现:

1、uuid1()——基于时间戳

由MAC地址、当前时间戳、随机数生成。可以保证全球范围内的唯一性,
但MAC的使用同时带来安全性问题,局域网中可以使用IP来代替MAC。

2、uuid2()——基于分布式计算环境DCE(Python中没有这个函数)

算法与uuid1相同,不同的是把时间戳的前4位置换为POSIX的UID。
实际中很少用到该方法。

3、uuid3()——基于名字的MD5散列值

通过计算名字和命名空间的MD5散列值得到,保证了同一命名空间中不同名字的唯一性,
和不同命名空间的唯一性,但同一命名空间的同一名字生成相同的uuid。

4、uuid4()——基于随机数

由伪随机数得到,有一定的重复概率,该概率可以计算出来。

5、uuid5()——基于名字的SHA-1散列值

算法与uuid3相同,不同的是使用 Secure Hash Algorithm 1 算法

源码

Source code: Lib/uuid.py

uuid模块包括:不可变对象UUID(UUID类)和函数uuid1()、uuid3()、uuid4()和uuid5(),后面的四个函数用于生成 RFC 4122 规范中指定的第1、3、4、5版UUID。使用uuid1()或uuid4()可以获得一个唯一的ID,uuid1()包含了主机的网络名称,uuid4()不涉及网络主机名,仅生成一个随机UUID,因此从隐私保护角度uuid4()更加安全。

枚举类型的SafeUUID 类

class uuid.SafeUUID

1
2
3
safe = 0
unsafe = -1
unknown = None

UUID 类(接口)

基本语法:

class uuid.UUID(hex=None, bytes=None, bytes_le=None, fields=None, int=None, version=None, **, is_safe=SafeUUID.unknown*)

下面的各种方法创建相同的UUID对象,

1
2
3
4
5
6
7
8
UUID('{12345678-1234-5678-1234-567812345678}')
UUID('12345678123456781234567812345678')
UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
UUID(bytes=b'\x12\x34\x56\x78'*4)
UUID(bytes_le=b'\x78\x56\x34\x12\x34\x12\x78\x56' +
b'\x12\x34\x56\x78\x12\x34\x56\x78')
UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
UUID(int=0x12345678123456781234567812345678)

其中:

如果尝试比较一个非UUID对象会引发TypeError
使用str()函数强制转换一个uuid对象,将会生成一个从12345678-1234-5678-1234-567812345678.中创建的字符串

只读属性

  • UUID.bytes

    指定一个大端字节序的总长16字节的字节串来创建UUID对象;

    1
    2
    3
    >>> u = uuid.UUID('{12345678-1234-5678-1234-567812345678}')
    >>> u.bytes
    b'\x124Vx\x124Vx\x124Vx\x124Vx'
  • UUID.bytes_le

    指定一个小端字节序的总长16字节的字节串来创建UUID对象;

    1
    2
    >>> u.bytes_le
    b'xV4\x124\x12xV\x124Vx\x124Vx'
  • UUID.fields

    以元组形式存放的UUID的6个整数域,有六个单独的属性和两个派生属性:

    | 域 | 意义 |
    | :———————————————————– | :——————— |
    | time_low | UUID的前32位 |
    | time_mid | 接前一域的16位 |
    | time_hi_version | 接前一域的16位 |
    | clock_seq_hi_variant | 接前一域的8位 |
    | clock_seq_low | 接前一域的8位 |
    | node | UUID的最后48位 |
    | time | UUID的总长60位的时间戳 |
    | clock_seq | 14位的序列号 |

    1
    2
    >>> u.fields
    (305419896, 4660, 22136, 18, 52, 95073701484152)
  • UUID.hex

    以32个字符表示的UUID

    1
    2
    >>> u.hex
    '12345678123456781234567812345678'
  • UUID.int

    以一个长度为128个二进制位的整数表示的UUID;

    1
    2
    >>> u.int
    24197857161011715162171839636988778104
  • UUID.urn

    以 RFC 4122 中指定的URN形式表示的UUID;

    1
    2
    >>> u.urn
    'urn:uuid:12345678-1234-5678-1234-567812345678'
  • UUID.variant

     UUID变体(variant),决定UUID内部的布局,已有的值为 RESERVED_NCS、RFC_4122、RESERVED_MICROSOFT 或 RESERVED_FUTURE;

1
2
>>> u.variant
'reserved for NCS compatibility'
  • UUID.version

    返回UUID的版本

    1
    2
    >>> u.version
    >>>

     这里由于u.variant == ‘reserved for NCS compatibility’,所以此处u.version为空。

  • UUID.is_safe

    枚举类型的SafeUUID对象,为了标识创建的UUID是否是线程安全的。

    1
    2
    >>> u.is_safe
    <SafeUUID.unknown: None>

    常量

关于属性variant,uuid模块定义了如下的常量

uuid.RESERVED_NCS
  该常量为兼容NCS而保留;
  
uuid.RFC_4122
  按照 RFC 4122 的规定来确定UUID的布局;
  
uuid.RESERVED_MICROSOFT
  该常量位兼容微软而保留
  
uuid.RESERVED_FUTURE
  该常量为未来可能的定义保留

1
2
3
4
5
6
7
8
9
10

可以在Python中查看这些常量:
>>> uuid.RESERVED_NCS
'reserved for NCS compatibility'
>>> uuid.RFC_4122
'specified in RFC 4122'
>>> uuid.RESERVED_MICROSOFT
'reserved for Microsoft compatibility'
>>> uuid.RESERVED_FUTURE
'reserved for future definition'

方法

  • uuid.getnode()

     获取硬件的地址并以48位二进制长度的正整数形式返回,这里所说的硬件地址是指网络接口的MAC地址,如果一个机器有多个网络接口,可能返回其中的任一个。如果获取失败,将按照RFC 4122的规定将随机返回的48位二进制整数的第8位设置成1。

    1
    2
    >>> uuid.getnode()
    202960192043486
  • uuid.uuid1(node=None, clock_seq=None)

     利用主机ID、序列号和当前时间生成一个UUID,如果参数 node 没有给定,会调用 getnode() 来获取硬件地址。如果参数中指定了 clock_seq ,使用参数中给定的时钟序列作为序列号,否则使用一个随机的14位长的序列号。

    1
    2
    >>> uuid.uuid1()
    UUID('97344912-4827-11ea-9c91-b8975a2679de')
  • uuid.uuid3(namespace, name)

    基于命名空间标识符(实质上是一个UUID)和一个名称(实质上是一个字符串)的MD5哈希值生成UUID。

  • uuid.uuid4()

    生成一个随机的UUID。

    1
    2
    >>> uuid.uuid4()
    UUID('ff3c991e-df64-4cfc-900e-ef83c991b513')
  • uuid.uuid5(namespace, name)

    基于命名空间标识符(实质上是一个UUID)和一个名称(实质上是一个字符串)的SHA-1哈希值生成UUID

下面的几个标准uuid在使用uuid3()uuid5()的时候使用

  • uuid.NAMESPACE_DNS

     当指定该命名空间时,参数 name 是一个完全限定的(fully-qualified)域名

  • uuid.NAMESPACE_URL

    当指定该命名空间时,参数 name 是一个URL

  • uuid.NAMESPACE_OID

    当指定该命名空间时,参数 name 是一个ISO OID

  • uuid.NAMESPACE_X500

    当指定该命名空间时,参数 name 是一个DER格式或文本格式的X.500 DN。

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
>>> import uuid

>>> # make a UUID based on the host ID and current time
>>> uuid.uuid1()
UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')

>>> # make a UUID using an MD5 hash of a namespace UUID and a name
>>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')

>>> # make a random UUID
>>> uuid.uuid4()
UUID('16fd2706-8baf-433b-82eb-8c7fada847da')

>>> # make a UUID using a SHA-1 hash of a namespace UUID and a name
>>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')

>>> # make a UUID from a string of hex digits (braces and hyphens ignored)
>>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')

>>> # convert a UUID to a string of hex digits in standard form
>>> str(x)
'00010203-0405-0607-0809-0a0b0c0d0e0f'

>>> # get the raw 16 bytes of the UUID
>>> x.bytes
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'

>>> # make a UUID from a 16-byte string
>>> uuid.UUID(bytes=x.bytes)
UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')

补充

如何去除UUID字符串中的横杠

1
2
3
4
uid = str(uuid.uuid4())
suid = ''.join(uid.split('-'))
## 等价于
print(uuid.uuid1().hex)
坚持原创技术分享,您的支持将鼓励我继续创作!