zoukankan      html  css  js  c++  java
  • Python3标准库:uuid 全局唯一标识符

    1. uuid 全局唯一标识符

    uuid 模块实现了全局唯一标识符(Universally Unique Identifier);这个RFC定义了一个系统,可以为资源创建唯一的标识符,这里采用一种不需要集中注册机的方式。UUID值为128位,正如参考指南所述,“UUID可以保证跨空间和时间的唯一性”。对于文档、主机、应用客户以及其他需要唯一值的情况,UUID可以用来生成标识符。这个RFC特别强调创建一个统一资源名(Uniform Resource Name)命名空间,并且涵盖了3个主要算法。

    • 使用IEEE802MAC地址作为唯一性来源
    • 使用伪随机数
    • 使用公开的串并结合密码散列

    在上述所有情况下,种子值都要与系统时钟结合,如果向后设置时钟,则要用一个时钟序列值维护唯一性。

    1.1 UUID1: IEEE 802 MAC地址

    UUID1值使用主机的MAC地址计算。uuid模块使用getnode()来获取当前系统的MAC值。

    import uuid
    
    print(hex(uuid.getnode()))

    如果一个系统有多个网卡,那么相应地便会有多个MAC地址,并且可能返回其中任意一个值。

    要为一个主机(由其MAC地址标识)生成一个UUID,需要使用uuid1()函数。节点标识符参数是可选的;如果没有设置这个域,那么便会使用getnode()返回的值。

    import uuid
    
    u = uuid.uuid1()
    
    print(u)
    print(type(u))
    print('bytes   :', repr(u.bytes))
    print('hex     :', u.hex)
    print('int     :', u.int)
    print('urn     :', u.urn)
    print('variant :', u.variant)
    print('version :', u.version)
    print('fields  :', u.fields)
    print('  time_low            : ', u.time_low)
    print('  time_mid            : ', u.time_mid)
    print('  time_hi_version     : ', u.time_hi_version)
    print('  clock_seq_hi_variant: ', u.clock_seq_hi_variant)
    print('  clock_seq_low       : ', u.clock_seq_low)
    print('  node                : ', u.node)
    print('  time                : ', u.time)
    print('  clock_seq           : ', u.clock_seq)

    对于返回的UUID对象,可以通过只读的实例属性访问它的各个部分。有些属性是UUID值的不同表示,如hex、int和urn。

    由于有时间分量(time),所以每次调用uuid1()都会返回一个新值。

    import uuid
    
    for i in range(3):
        print(uuid.uuid1())

    在这个输出中,只有时间分量(串的开始部分)有变化。

    由于每个计算机有不同的MAC地址,所以在不同系统上运行这个示例程序会生成完全不同的值。下一个例子传递不同的节点ID来模拟在不同主机上运行。

    import uuid
    
    for node in [0x1ec200d9e0, 0x1e5274040e]:
        print(uuid.uuid1(node), hex(node))

    除了返回不同的时间值,UUID末尾的节点标识符也有变化。

    1.2 UUID 3和5 基于名字的值

    有些情况下可能需要根据名字创建UUID值,而不是根据随机值或基于时间的值来创建。UUID3和5规范使用密码散列值(分别使用MD5或SHA-1),将特定于命名空间的种子值与名字相结合。有一些由预定义UUID值标识的公开的命名空间,分别用于处理DNS、URL、ISO OID和X.500识别名(Distinguished Name)。通过生成和保存UUID值,还可以定义新的特定于应用的命名空间。

    import uuid
    
    hostnames = ['www.doughellmann.com', 'blog.doughellmann.com']
    
    for name in hostnames:
        print(name)
        print('  MD5   :', uuid.uuid3(uuid.NAMESPACE_DNS, name))
        print('  SHA-1 :', uuid.uuid5(uuid.NAMESPACE_DNS, name))
        print()

    要从一个DNS名创建UUID,可以把uuid.NAMESPACE_DNS作为命名空间参数传入uuid3()或uuid5()。

    不论什么时间计算或者在哪里计算,一个命名空间中给定名的UUID值总是相同的。

    import uuid
    
    namespace_types = sorted(
        n
        for n in dir(uuid)
        if n.startswith('NAMESPACE_')
    )
    name = 'www.doughellmann.com'
    
    for namespace_type in namespace_types:
        print(namespace_type)
        namespace_uuid = getattr(uuid, namespace_type)
        print(' ', uuid.uuid3(namespace_uuid, name))
        print(' ', uuid.uuid3(namespace_uuid, name))
        print()

    但是命名空间中相同名字的UUID值则是不同的。

    1.3 UUID 4 随机数

    有时,基于主机和基于命名空间的UUID值“差别还不够大”。例如,如果UUID要作为散列键,则需要有区分度更大、更随机的值序列来避免散列表中出现冲突。让值有更少的共同数字也能更容易地在日志文件中查找这些值。为了增加UUID的区分度,可以使用uuid4()利用随机的输入值生成UUID。

    import uuid
    
    for i in range(3):
        print(uuid.uuid4())

    随机性的来源取决于导入uuid时哪些C库可用。如果可以加载libuuid(或uuid.d11),而且其中包含一个生成随机值的函数,那么便使用这个函数。否则,使用os.urandom()或random模块。

    1.4 处理UUID对象

    除了生成新的UUID值,还可以解析标准格式的串以创建UUID对象,使比较和排序操作的处理更为容易。

    import uuid
    
    def show(msg, l):
        print(msg)
        for v in l:
            print(' ', v)
        print()
    
    input_values = [
        'urn:uuid:f2f84497-b3bf-493a-bba9-7c68e6def80b',
        '{417a5ebb-01f7-4ed5-aeac-3d56cd5037b0}',
        '2115773a-5bf1-11dd-ab48-001ec200d9e0',
    ]
    
    show('input_values', input_values)
    
    uuids = [uuid.UUID(s) for s in input_values]
    show('converted to uuids', uuids)
    
    uuids.sort()
    show('sorted', uuids)

    从输入中去除外围大括号,另外将短横线(-)也去除。如果串有一个包含urn:或uuid:的前缀,则这个前缀也会被删除。剩下的文本必然是由十六进制数构成的串,然后再将它解释为一个UUID值。

  • 相关阅读:
    Codeforces Round #251 (Div. 2) A
    topcoder SRM 623 DIV2 CatAndRat
    topcoder SRM 623 DIV2 CatchTheBeatEasy
    topcoder SRM 622 DIV2 FibonacciDiv2
    topcoder SRM 622 DIV2 BoxesDiv2
    Leetcode Linked List Cycle II
    leetcode Linked List Cycle
    Leetcode Search Insert Position
    关于vim插件
    Codeforces Round #248 (Div. 2) B. Kuriyama Mirai's Stones
  • 原文地址:https://www.cnblogs.com/liuhui0308/p/12665600.html
Copyright © 2011-2022 走看看