• uuid 模块


    uuid 模块:

    介绍:

        中文是通用唯一识别码,UUID 的目的是让分布式系统中的所有元素都能有唯一的识别信息。如此一来,每个人都可以创建不与其它人冲突的 UUID,就不需考虑数据库创建时的名称重复问题
        
        
        UUID 是由一组32位数的16进制数字所构成,是故 UUID 理论上的总数为1632=2128,约等于3.4 x 10123。
    
    也就是说若每纳秒产生1百万个 UUID,要花100亿年才会将所有 UUID 用完
    
        UUID 的十六个八位字节被表示为 32个十六进制数字,以连字号分隔的五组来显示,形式为 8-4-4-4-12,总共有 36个字符(即三十二个英数字母和四个连字号)
     eg:
        123e4567-e89b-12d3-a456-426655440000
        
    
    为什么使用uuid:
        很多应用场景需要一个id, 但是又不要求这个id 有具体的意义, 仅仅用来标识一个对象. 常见的例子有数据库表的id 字段. 另一个例子是前端的各种UI库, 因为它们通常需要动态创建各种UI元素, 这些元素需要唯一的id , 这时候就需要使用UUID
    

    版本:

    xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
    
    数字 M的四位表示 UUID 版本,当前规范有5个版本,M可选值为1, 2, 3, 4, 5 ;
    
    。这5个版本使用不同算法,利用不同的信息来产生UUID,各版本有各自优势,适用于不同情景。具体使用的信息
    
    version 1, date-time & MAC address
    version 2, date-time & group/user id
    version 3, MD5 hash & namespace
    version 4, pseudo-random number
    version 5, SHA-1 hash & namespace
    
        使用较多的是版本1和版本4,其中版本1使用当前时间戳和MAC地址信息。版本4使用(伪)随机数信息,128bit中,除去版本确定的4bit和variant确定的2bit,其它122bit全部由(伪)随机数信息确定。
    
        因为时间戳和随机数的唯一性,版本1和版本4总是生成唯一的标识符。若希望对给定的一个字符串总是能生成相同的 UUID,使用版本3或版本5。
        
    

    python -- uuid 模块:

        生成UUID的概率不为零,但是无限接近零,因此可以忽略不记,如此一来,每个人都可以建立不与其他人冲突的UUID。	
        
     uuid1():
        
        从主机ID、序列号和当前时间生成UUID。如果未给定“node”,则使用getnode() 获取硬件地址。如果给出“时钟序列”,则将其用作序列号;否则,将选择随机的14位序列号
        def uuid(node=None, clock_seq=None):
      ...
      return UUID(fields=(time_low, time_mid, time_hi_version, clock_seq_hi_variant, clock_seq_low, node), version=1)
    
    
    需要注意的是: python中没有uuid2()这个函数!!
    
    
    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
       hash = md5(namespace.bytes + bytes(name, "utf-8")).digest()
       return UUID(bytes=hash[:16], version=3)
    
    
    uuid4()
    
    基于随机数生成的UUID
    # 源码参考
    
     import os
     def uuid4():
         """Generate a random UUID."""
        return UUID(bytes=os.urandom(16), version=4)
    
    
    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)
        
    

    x详解:

    uuid1() 中的getnode()
    
        获取硬件的地址并以48位二进制长度的整数形式返回,这里所说的硬件地址是指网络接口的MAC 地址,如果一个机器有多个网络接口,可能返回其中的任一个。如果获取失败,将按照“RFC 4122” 的规定随机返回48位数字,并将第8位设置为1(其组播位(第一个八位位组的最低有效位)设置为1)
        
        
    uuid3()和uuid5()中提到的命名空间标识符,uuid模块定义了如下的备选项:
    
        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或文本输出格式
    
    这些标识符在源码中统一指向 UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8'),因此命名空间仅仅作为标识用,定义了name 参数的格式
     
    

    功能分析:

    UUID实际应用
    
        uuid1 适应用分布式计算环境,具有高度的唯一性;
        uuid3 和uuid5 适合于一定范围的名字唯一,且需要或可能重复生成UUID 的环境下;
        uuid4 最简单,但完全随机,不可控,建议可以在DRF 生成和验证JWT 时做用户的SECRET_KEY 用,用来保证用户每次登录,异设备同时登录,修改密码等操作,JWT 失效问题
        
        
    UUID 的劣势
    
        1.varchar(36)字符串占用空间比较大,但携带的信息很少,且不直观
        2.以此建立索引的时候,非常耗性能且慢
        3.UUID 是无序的,但是业务系统很多时候希望生成的 是有序的,或者粗略有序
    

    实践:

    >>> 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
    'x00x01x02x03x04x05x06x07x08	
    x0bx0c
    x0ex0f'
    
    >>> # make a UUID from a 16-byte string
    >>> uuid.UUID(bytes=x.bytes)
    UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
    
  • 相关阅读:
    git切换仓库 小记
    修改prometheus默认端口,修改grafana默认端口
    Redisson报错
    Windows IDEA Community 报错
    Debouncer防抖代码
    IDEA通用配置
    Jackson通用工具类
    SpringBoot接入两套kafka集群
    博客园什么时候有的高低贵贱制度???
    致已经逝去的2020和已经到来的2021
  • 原文地址:https://www.cnblogs.com/shaozheng/p/12121385.html
Copyright © 2020-2023  润新知