python:uuid模块使用与源码解读

简介:通用唯一识别码(英语:Universally Unique Identifier,简称UUID)是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领域的一部分。它是通过MAC地址, 时间戳, 命名空间, 随机数, 伪随机数来保证生成ID的唯一性, 有着固定的大小( 128 bit )。

组成分析:UUID是由一组32位数的16进制数字所构成,是故UUID理论上的总数为16=2,约等于3.4 x 10。也就是说若每纳秒产生1兆个UUID,要花100亿年才会将所有UUID用完。UUID的标准型式包含32个16进制数字,以连字号分为五段,形式为8-4-4-4-12的32个字符。

它的唯一性和一致性特点使得可以无需注册过程就能够产生一个新的UUID. UUID可以被用作多种用途, 既可以用来短时间内标记一个对象, 也可以可靠的辨别网络中的持久性对象.

应用场景:需要一个唯一的id, 但是又不要求这个id有具体的意义, 仅仅用来标识一个对象。例如接口测试中每次都需要传入不重复的编号,如果使用时间戳time.time()等形式。

如果只是单纯使用时间戳,在执行高效的情况下,基本都容易造成前后时间戳一致的情况。在没有其他要求的场景下,建议可以使用uuid。

基本使用:

import uuid

print(uuid.uuid1())
print(uuid.uuid3(namespace=uuid.NAMESPACE_DNS, name="tom"))
print(uuid.uuid4())
print(uuid.uuid5(namespace=uuid.NAMESPACE_URL, name="tom"))

文末uuid模块提供了供uuid3()和uuid5()的标准UUID。

NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8')
NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8')
NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8')

uuid.uuid1()源码和解读:根据主机ID、序列号和当前时间生成UUID。如果未给出“node”,则使用getnode()获取硬件地址。如果给出“时钟顺序”,则将其用作序列号;否则,将选择一个随机的14位序列号。”“”#当系统提供版本1 UUID生成器时,请使用它(但不要#在此处使用UuidCreate,因为其UUID不符合RFC 4122)。其中nanoseconds = time.time_ns()使用到了纳秒级别参与数据处理。

def uuid1(node=None, clock_seq=None):
    """Generate a UUID from a host ID, sequence number, and the current time.
    If 'node' is not given, getnode() is used to obtain the hardware
    address.  If 'clock_seq' is given, it is used as the sequence number;
    otherwise a random 14-bit sequence number is chosen."""

    # When the system provides a version-1 UUID generator, use it (but don't
    # use UuidCreate here because its UUIDs don't conform to RFC 4122).
    if _generate_time_safe is not None and node is clock_seq is None:
        uuid_time, safely_generated = _generate_time_safe()
        try:
            is_safe = SafeUUID(safely_generated)
        except ValueError:
            is_safe = SafeUUID.unknown
        return UUID(bytes=uuid_time, is_safe=is_safe)

    global _last_timestamp
    import time
    nanoseconds = time.time_ns()
    # 0x01b21dd213814000 is the number of 100-ns intervals between the
    # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
    timestamp = nanoseconds // 100 + 0x01b21dd213814000
    if _last_timestamp is not None and timestamp <= _last_timestamp:
        timestamp = _last_timestamp + 1
    _last_timestamp = timestamp
    if clock_seq is None:
        import random
        clock_seq = random.getrandbits(14) # instead of stable storage
    time_low = timestamp & 0xffffffff
    time_mid = (timestamp >> 32) & 0xffff
    time_hi_version = (timestamp >> 48) & 0x0fff
    clock_seq_low = clock_seq & 0xff
    clock_seq_hi_variant = (clock_seq >> 8) & 0x3f
    if node is None:
        node = getnode()
    return UUID(fields=(time_low, time_mid, time_hi_version,
                        clock_seq_hi_variant, clock_seq_low, node), version=1)

uuid.uuid3()源码和解读:基于命名空间UUID和名称的MD5哈希生成UUID。

def uuid3(namespace, name):
    """Generate a UUID from the MD5 hash of a namespace UUID and a name."""
    from hashlib import md5
    digest = md5(
        namespace.bytes + bytes(name, "utf-8"),
        usedforsecurity=False
    ).digest()
    return UUID(bytes=digest[:16], version=3)

uuid.uuid4()源码和解读:基于os模块的urandom()随机值生成UUID。

def uuid4():
    """Generate a random UUID."""
    return UUID(bytes=os.urandom(16), version=4)

uuid.uuid5()源码和解读:基于名称空间UUID和名称的SHA-1哈希生成UUID。

def uuid5(namespace, name):
    """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
    from hashlib import sha1
    hash = sha1(namespace.bytes + bytes(name, "utf-8")).digest()
    return UUID(bytes=hash[:16], version=5)

总结:一般情况下使用uuid.uuid4()即可。

import uuid
result = uuid.uuid4()
print(result)

你可能感兴趣的:(python:uuid模块使用与源码解读)