Python标准库uuid模块(生成唯一标识)详解

目录
  • UUID格式组成
  • Python 中的uuid 模块
  • uuid1() 中的getnode()
  • UUID实际应用
  • UUID 的劣势
  • 参考资料:
  • 总结

UUID (Universally Unique Identifier,通用唯一标识)是一个128位的用于计算机系统中以识别信息的数目,虽然生成UUID的概率不为零,但是无限接近零,因此可以忽略不记,如此一来,每个人都可以建立不与其他人冲突的UUID。

UUID格式组成

规范的文本中,UUID的十六个八位字节标识位32个十六进制(基数16)数字,显示在由字符分割的五个组中,8-4-4-4-12总格36个字符(32个字母数字字符和4个连字符),如:

123e4567-e89b-12d3-a456-426655440000
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

其中M代表版本,由下面的知识可知,这个UUID 可能是通过Python的 uuid.uuid1(node, clock_seq)生成

Python 中的uuid 模块

在Python 2.5以后引入,接口包括:不可变对象UUID(UUID类)和函数uuid1()、uuid3()、uuid4()、uuid5(),后面四个函数用于生成“RFC 4122” 规范中指定的第1、3、4、5版UUID。具体算法如下:

UUID()

class uuid.UUID([hex[, bytes[, bytes_le[, fields[, int[, version]]]]]]) 
  该类用于从参数给定的内容中实例化UUID对象(hex, bytes, bytes_le, fields, int 必须且只能指定一个):
  hex:指定32个字符以创建UUID对象,当指定一个32个字符构成的字符串来创建一个UUID对象时,花括号、连字符和URN前缀等都是可选的;
  bytes:指定一个大端字节序的总长16字节的字节串来创建UUID对象;
  bytes_le:指定一个小端字节序的总长16字节的字节串来创建UUID对象;
  fields:指定6个整数域,共计128位来创建UUID(其中,32位作为time_low段,16位作为time_mid段,16位作为time_hi_version段,8位作为clock_seq_hi_variant段,8位作为clock_seq_low段,48位作为node段);
  int:直接指定一个长度为128个二进制位的整数用于创建UUID对象;
  version:(可选)指定UUID的版本,从1到5,一旦指定了该参数,生成的UUID将具有自己的变体(variant)和版本数,具体请参考RFC 4122

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

u = UUID('{12345678-1234-5678-1234-567812345678}')
u = UUID(hex = '12345678123456781234567812345678')
u = UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
u = UUID(bytes='\x12\x34\x56\x78'*4)
u = UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' +
  '\x12\x34\x56\x78\x12\x34\x56\x78')
u = UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
u = UUID(int=0x12345678123456781234567812345678)

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)

fields 各个参数含义如下图:

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)

由源码可知,uuid1() 使用的是 UUID(fields=(...))

      uuid3()、uuid4()、uuid5() 均使用的是 UUID(bytes=...)

“RFC 4122” 推荐使用版本5(SHA1)而不是版本3(MD5)

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 是无序的,但是业务系统很多时候希望生成的 是有序的,或者粗略有序

参考资料:

  • uuid — UUID objects according to RFC 4122 https://docs.python.org/3/library/uuid.html
  • Python--uuid http://www.cnblogs.com/Security-Darren/p/4252868.html
  • Python 使用UUID 库生成唯一ID https://www.cnblogs.com/kaituorensheng/p/5530902.html
  • Universally unique identifier https://en.wikipedia.org/wiki/Universally_unique_identifier
  • 使用UUID的劣势 https://blog.csdn.net/woshiyexinjie/article/details/83351677

总结

到此这篇关于Python标准库uuid模块(生成唯一标识)的文章就介绍到这了,更多相关Python标准库uuid模块内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python uuid模块使用实例

    uuid是一种唯一标识,在许多领域作为标识用途.python的uuid模块就是用来生成它的. 闲话不说,python提供的生成uuid的方法一共有4种,分别是: 1.从硬件地址和时间生成 2.从md5算法生成 3.随机生成 4.从SHA-1算法生成 他们在uuid模块里对应uuid1, uuid3, uuid4, uuid5这几个方法,注意没有uuid2. 下面是示例: 复制代码 代码如下: #-*- encoding: gb2312 -*- import uuid print uuid.uui

  • Python内置模块hashlib、hmac与uuid用法分析

    本文实例讲述了Python内置模块hashlib.hmac与uuid用法.分享给大家供大家参考,具体如下: 一.hashlib md5和sha算法通过消息摘要算法生成定长的消息摘要,消息摘要算法是不可逆的.但同一段消息通过摘要算法后得到的值是一样的,可一通过比对消息摘要验证数据的完整性. sha算法比MD5算法安全,但所需的时间也稍长. 1.原始消息摘要 import hashlib # ######## md5 ######## hash = hashlib.md5() hash.update

  • Python通用唯一标识符uuid模块使用案例

    1. 背景知识: UUID: 通用唯一标识符 ( Universally Unique Identifier ), 对于所有的UUID它可以保证在空间和时间上的唯一性. 它是通过MAC地址, 时间戳, 命名空间, 随机数, 伪随机数来保证生成ID的唯一性, 有着固定的大小( 128 bit ). 它的唯一性和一致性特点使得可以无需注册过程就能够产生一个新的UUID. UUID可以被用作多种用途, 既可以用来短时间内标记一个对象, 也可以可靠的辨别网络中的持久性对象. 为什么要使用UUID? 很多

  • python中uuid模块实例浅析

    很多人不明白,学习这些冷门的函数基本上都用不到,或者说是什么多大用处,事实上,有是有很多用处的,比如今天给大家介绍的uuid模块,就能够生成一个真正的随机数,还可以给数据库生成唯一ID,很多地方都可以用到的,感兴趣的小伙伴,可以跟着小编,一起来认真的学习了解下啦. 模块安装: pip install uuid 模块导入: import uuid 使用场景: 1.能够生成时间戳 2.可以生成随机数 使用方法: import uuid uuid.uuid3(uuid.NAMESPACE_DNS, '

  • Python标准库uuid模块(生成唯一标识)详解

    目录 UUID格式组成 Python 中的uuid 模块 uuid1() 中的getnode() UUID实际应用 UUID 的劣势 参考资料: 总结 UUID (Universally Unique Identifier,通用唯一标识)是一个128位的用于计算机系统中以识别信息的数目,虽然生成UUID的概率不为零,但是无限接近零,因此可以忽略不记,如此一来,每个人都可以建立不与其他人冲突的UUID. UUID格式组成 规范的文本中,UUID的十六个八位字节标识位32个十六进制(基数16)数字,

  • python标准库压缩包模块zipfile和tarfile详解(常用标准库)

    目录 常用的标准库 zip格式 ZipFile参数说明 操作含义 压缩方法 常用方法 tar包 和 gz.bz2.xz格式 删除压缩包中的文件 常用的标准库 在我们常用的系统windows和Linux系统中有很多支持的压缩包格式,包括但不限于以下种类:rar.zip.tar,以下的标准库的作用就是用于压缩解压缩其中一些格式的压缩包. zip格式 import zipfile zipfile模块操作压缩包使用ZipFile类进行操作,使用方法和open的使用方法很相似,也是使用r.w.x.a四种操

  • Python标准库中的logging用法示例详解

    目录 1.logging的介绍 2.简单用法示例 3.日志级别 4.打印格式的各个参数 5.日志输出到指定文件 6.日志回滚(按照文件大小滚动) 7.日志回滚(按照时间滚动) 1.logging的介绍 logging是Python标准库中记录常用的记录日志库,通过logging模块存储各种格式的日志,主要用于输出运行日志,可以设置输出日志的等级.日志保存路径.日志文件回滚等. 2.简单用法示例 首先创建一个logger.py的文件,其里面的代码如下所示: import logging # 1.创

  • Python标准库06之子进程 (subprocess包) 详解

    这里的内容以Linux进程基础和Linux文本流为基础.subprocess包主要功能是执行外部的命令和程序.比如说,我需要使用wget下载文件.我在Python中调用wget程序.从这个意义上来说,subprocess的功能与shell类似. subprocess以及常用的封装函数 当我们运行python的时候,我们都是在创建并运行一个进程.正如我们在Linux进程基础中介绍的那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序.在Python中,我们通过标准库中的subp

  • python标准库OS模块详解

    python标准库OS模块简介 os就是"operating system"的缩写,顾名思义,os模块提供的就是各种 Python 程序与操作系统进行交互的接口.通过使用os模块,一方面可以方便地与操作系统进行交互,另一方面页可以极大增强代码的可移植性.如果该模块中相关功能出错,会抛出OSError异常或其子类异常. 注意 如果是读写文件的话,建议使用内置函数open(): 如果是路径相关的操作,建议使用os的子模块os.path: 如果要逐行读取多个文件,建议使用fileinput模

  • python标准库OS模块函数列表与实例全解

    Python OS模块库详解 os就是"operating system"的缩写,顾名思义,os模块提供的就是各种 Python 程序与操作系统进行交互的接口.通过使用os模块,一方面可以方便地与操作系统进行交互,另一方面页可以极大增强代码的可移植性.如果该模块中相关功能出错,会抛出OSError异常或其子类异常. 注意 如果是读写文件的话,建议使用内置函数open(): 如果是路径相关的操作,建议使用os的子模块os.path: 如果要逐行读取多个文件,建议使用fileinput模块

  • 代码解析python标准库logging模块

    目录 问题1:如何获取caller的(文件名,行号,函数名)? findCaller内容如下: currentframe函数的定义: 问题2: Logger对象的层级,父子关系如何实现的? Manager的getLogger()定义如下: 问题1:如何获取caller的(文件名,行号,函数名)? 当新增一条log记录时,最终将调用Logger类的_log方法,这个方法首先会创建一个LogRecord对象.LogRecord对象需要(filename, lineno, funcname)参数信息.

  • python标准库random模块处理随机数

    目录 前言 1. 常用函数 2. 不常用函数 3. 使用示例 3.1 生成随机密码 前言 random模块实现了各种分布的伪随机数生成器. 伪随机数:人类使用算法等方式,以一个基准(也被称为种子,常用的是时间戳)来构造一系列数字,这些数字的特性符合人们所理解的随机数.一旦算法和种子都确定,产生的随机数序列也是确定的,所以称为伪随机数. 1. 常用函数 常用函数 说明 random.seed(a) 设置初始化随机种子,可输出相同随机数序列:a取整数或浮点数,不设置时默认以系统时间为种子 rando

  • Python写脚本常用模块OS基础用法详解

    收集了一些关于OS库的用法,整理归纳一下,方便使用 import os # 系统操作 print(os.sep) # 获取当前系统的路径分隔符 print(os.name) # 获取当前使用的工作平台 print(os.getenv('PATH')) # 获取名为 PATH 的环境变量 print(os.getcwd()) # 获取当前的路径 print(os.environ['PATH']) # 可以返回环境相关的信息 不传参时,以字典的方式返回所有环境变量 # 调用系统命令 os.syste

  • Python实现学生管理系统并生成exe可执行文件详解流程

    目录 一.准备工作 二.代码流程 三.打包exe可执行程序 话说这能难倒我吗?赶赶单单~ 来 ,开搞! 一.准备工作 用到的软件准备一哈 Python 3.8 Pycharm 2021.2 知识点 Python基础语法 基本的数据类型与结构 基本的逻辑控制语句 实战小项目 二.代码流程 = 赋值 就是把等号左边的内容 用 等号右边的这个变量名字 接收 msg = """************************************************** 欢迎使

随机推荐