上一篇 :
无实例理解Python中的UUID模块
在本文中,我们将学习如何使用Python UUID模块生成通用唯一标识符。对各种版本的UUID。我们将逐一举例说明每个例子。
本文的目标:
- 如何生成RFC 4122中指定的版本1、3、4和5 UUID
- 为什么和何时使用UUID
- 使用MAC地址,序列号和当前时间生成版本1 UUID。
- 获取版本4的加密安全随机UUID
- 生成基于UUID 3和5的名称和加密哈希值。
- 了解UUID的结构
- 将UUID转换为其字符串表示形式。
- 将UUID的String表示形式转换为有效的UUID实例。
- 使用种子值生成可再现的UUID
- 从UUID提取UUID属性
- 最后,什么是安全和不安全的UUID
什么是UUID
UUID是一个通用唯一标识符。您也可以将其称为GUID,即全局唯一标识符。但是,这是什么?让我们简单地了解一下。
UUID是128位长的数字或ID,用于唯一标识计算机系统中的文档,用户,资源或信息。
- UUID可以保证标识符在空间和时间上的唯一性。当我们谈论空间和时间时,是指当根据标准生成UUID时,标识符不会重复已经创建的标识符或将被创建以标识其他事物的标识符。
- 因此,在需要唯一值的情况下,UUID很有用。
您想要了解更多有关什么是UUID的信息吗?然后参考这个 维基百科链接。
根据RFC 4122实现的Python UUID模块 。RFC 4122是Internet协会的标准和版权(C)。R FC 4122规范包括所有详细信息和算法,以生成所有版本的唯一标识符。RFC 4122文档指定了三种生成UUID的算法。
因此,使用Python UUID模块,您可以生成版本1、3、4和5 UUID。使用此模块生成的UUID是不可变的。
Python UUID模块支持以下版本的UUID。
- UUID1 –使用主机MAC地址,序列号和当前时间生成UUID。此版本使用IEEE 802 MAC地址。
- UUID3和UUID 5使用加密哈希和应用程序提供的文本字符串来生成UUID。UUID 3使用MD5哈希,而UUID 5使用SHA-1哈希。
- UUID4使用伪随机数生成器生成UUID。
现在,让我们看一个简单的示例以获取通用唯一ID。
import uuid
# make a UUID based on the host address and current time
uuidOne = uuid.uuid1()
print ("Printing my First UUID of version 1")
print(uuidOne)
UUID的结构
正如您在输出中看到的,UUID由五个组件组成,每个组件都有固定的长度。连字符将各个部分分开。UUID的格式为“ 8-4-4-4-12”。
UUID字符串表示形式的正式定义如下。
UUID = time_low “-” time_mid “-“timehighand_version ” “clockseqandreservedAndclockseq_low“-” Node.
让我们了解为什么和何时在我们的应用程序中使用UUID。
为什么和何时使用UUID
注意:何时使用UUID取决于情况,用例,条件和复杂性。
- 生成唯一的统一资源名称。UUID具有固定大小(128位),与其他替代方法相比,它很小。如您所知,UUID是唯一且持久的,它是统一资源名称的绝佳选择
- 生成UUID不需要注册过程
- 我们甚至可以将UUID用作交易ID
- 在加密应用程序中的显着用途
在Web应用程序中
- UUID也很方便生成唯一的会话ID,以帮助状态管理。
- 生成用户ID。如果使用自动增量值生成用户ID,则非常简单且容易猜到。人们可以使用整数值来猜测并尝试使用用户ID访问用户。但是,当您使用UUID时,很难猜测,因为UUID并非以任何顺序格式创建的,因此很难猜测其顺序。
在数据库系统中
- UUID具有显着的优势,因为UUID与环境无关。即,在使用任何应用程序的任何计算机上生成的UUID都是唯一的。
- 由于大多数应用程序都依赖于基础数据库服务器来生成唯一键或主键。如果我们想更改密钥生成不同的数据库该怎么办。在这种情况下,一个不错的选择是在应用程序中使用UUID生成唯一的数据库密钥。
- 同样,UUID也适用于分布式环境。我们可以拆分一个表并将其放置在多个物理数据库服务器上。如果我们有一个自动增量密钥,我们必须开发一个合适的算法来管理它。
- 同样,UUID是一个实值,而不是像SQL表中的数字一样的伪值。
考虑以上情况时,实际上UUID方法在生成数据库密钥方面更为独特和通用。由于自动增量不适用于分布式系统,因此大多数数据库服务器(包括MS SQL Server,MySQL或Oracle)以及更多数据库服务器使用UUID生成数据库密钥,以唯一地标识资源或信息。
最后,让我们看看现在如何使用UUID模块及其功能。
UUID 1以使用MAC地址生成唯一ID
该uuid.uuid1()
函数用于根据主机ID,序列号和当前时间生成UUID。它使用主机的MAC地址作为唯一性来源。
uuid1()的语法
uuid.uuid1(node=None, clock_seq=None)
- 该节点和clock_seq可选的参数。
- 节点是硬件地址,它是一个48位正整数。如果未给出节点,则使用
uuid.getnode()
功能来获取当前主机的通用管理的MAC地址。 - 如果给定clock_seq,它将用作序列号。否则,选择一个随机的14位序列号。
使用MAC Address为主机生成唯一ID的示例。
import uuid
# Generate a UUID from a host ID, sequence number, and the current time
uuidOne = uuid.uuid1()
print("UUID of version one", uuidOne)
注意:uuid1是不安全的,因为它以UUID显示计算机的网络地址,因此存在隐私问题。
使用节点和时钟序列为主机生成唯一ID的示例
每台计算机都有不同的MAC地址,因此在每台计算机上您将获得不同的ID。让我们通过设置显式节点ID来模拟在不同主机上运行来对此进行模拟。
import uuid
# Generate a UUID using a clock sequence and node
print("UUID of version one")
clock_seq = 4115
for node in [0xccaf789d94a0, 0xadaf456d94a0]:
print(uuid.uuid1(node, clock_seq))
uuid.getnode()
要生成版本1的UUID,我们需要一个硬件地址,即MAC地址。它是一个48位正整数。
- 该
uuid.getnode()
函数用于获取网络接口的MAC地址。如果机器具有多个网络接口,则返回通用管理的MAC地址,而不是通过本地管理的MAC地址返回。管理的MAC地址保证是全局唯一的 - 如果getnode()函数无法获取MAC地址,则它会按照RFC 4122中的建议返回带有多播位的随机48位数字。
示例:
import uuid
# Get the hardware address as a 48-bit positive integer
print("MAC address integer format", uuid.getnode())
print("MAC address Hex format", hex(uuid.getnode()))
UUID 4以生成随机UUID
使用uuid4()函数生成的UUID是使用真正的Random或Pseudo-Random生成器创建的。
现在来看示例。
import uuid
for i in range(2):
uuidFour = uuid.uuid4()
print("uuid of version four", uuidFour)
什么时候应该在python中使用uuid1和uuid4?
确保uuid1()不会产生任何冲突。您可以通过在不到100ns的时间内创建更多的16384 uuid1来创建重复的UUID。当您不想使计算机的MAC地址可见时,请不要使用uuid1。
UUID4()使用加密安全的随机数生成器生成UUID。
uuid4()生成一个随机UUID。碰撞的机会很小。如果需要在单独的计算机上生成UUID,或者要生成安全的UUID,请使用UUID4()。
此外,鲍勃·阿曼(Bob Aman)在StackOverflow上的出色回答 详细解释了这一点。
UUID 3和UUID 5创建基于名称的UUID
第3版或第5版UUID用于从“名称”生成UUID。我们可以使用名称和名称空间来创建一系列唯一的UUID。简单来说,3和5个UUID就是带有名称的哈希名称空间标识符。
所述uuid.uuid3(namespace, name)
基于所述一个UUID MD5一个命名空间标识符(这是一个UUID)的散列和字符串。
同样,uuid.uuid5(namespace, name)
根据名称空间标识符(是UUID)和名称的SHA-1哈希技术生成UUID 。
的 UUID模块定义了以下命名空间标识符与uuid3()或uuid5()来使用。
- UUID.NAMESPACE_DNS表示标准域名。例如,https://pynative.com。
- UUID.NAMESPACE_URL指定此名称空间时,表示它是一个URL。
- UUID.NAMESPACE_OID指定此命名空间后,名称字符串为ISO OID。
- UUID.NAMESPACE_X500指定此命名空间后,名称字符串是DER或文本输出格式的X.500 DN。
现在来看示例。使用不同的主机名和名称空间生成UUID 3和UUID 5。
import uuid
hostNames = ['pynative.com', 'stackoverflow.com']
for host in hostNames:
print('Generate uuid of version 3 using name as',host,' and namespace as uuid.NAMESPACE_DNS')
print(uuid.uuid3(uuid.NAMESPACE_DNS, host))
print('Generate uuid of version 5 using name as', host, ' and namespace as uuid.NAMESPACE_DNS'),
print(uuid.uuid5(uuid.NAMESPACE_DNS, host))
print()
使用不同名称空间生成UUID 3和UUID 5的示例。
import uuid
nameSpaces = [uuid.NAMESPACE_DNS, uuid.NAMESPACE_URL, uuid.NAMESPACE_OID, uuid.NAMESPACE_X500]
hostName = 'pynative.com'
print("Generate uuid using namespace")
for namespace in nameSpaces:
print('uuid 3 is', uuid.uuid3(namespace, hostName))
print('uuid 5 is', uuid.uuid5(namespace, hostName))
print()
uuid3和UUID 5的行为:–
- 使用相同名称空间和相同名称在不同时间生成的UUID相等。
- 从同一名称空间中的两个不同名称生成的唯一ID是不同的。
- 在两个不同的命名空间中,由相同名称生成的UUID是不同的。
示例:您应该两次都获得相同的UUID。
import uuid
print('Generate uuid of version 3 using name as pynative.com and namespace as uuid.NAMESPACE_DNS')
print(uuid.uuid3(uuid.NAMESPACE_DNS, "pynative.com"))
print('Generate uuid of version 3 using name as pynative.com and namespace as uuid.NAMESPACE_DNS')
print(uuid.uuid3(uuid.NAMESPACE_DNS, "pynative.com"))
提取UUID属性只读属性
UUID的内部表示是内存中特定的位序列,如RFC4211中所述。必须将位序列转换为字符串表示形式,以字符串格式表示UUID。
UUID模块提供各种只读参数来访问UUID对象的每个组件的值。您可以从UUID中提取值,以便我们可以将此值用于其他目的。例如,您要从python中的UUID version1中提取时间。
UUID只读属性包括以下内容:–
- UUID.bytes: UUID为16字节的字符串(包含按big-endian字节顺序排列的六个整数字段)。
- UUID.bytes_le:这是一个16字节的字符串,由timelow,timemid和timehiversion组成。
- UUID.fields: UUID的六个整数字段的元组,也可以作为六个单独的属性和两个派生的属性使用:UUID.fields具有以下字段。
字段 | 含义 |
---|---|
time_low | UUID的前32位 |
time_mid | UUID的后16位 |
timehiversion | UUID的后16位 |
clockseqhi_variant | UUID的后8位 |
clockseqlow | UUID的后8位 |
node | UUID的后48位 |
time | 60位时间戳 |
clock_seq | 14位序号 |
- UUID.hex: UUID为32个字符的十六进制字符串。
- UUID.int:UUID的整数表示形式,为128位整数。
- UUID.urn: UUID作为统一资源名称。
- UUID.variant: UUID变体,它确定UUID的内部布局。这将是常量RESERVEDNCS,RFC4122,RESERVEDMICROSOFT或RESERVEDFUTURE之一。
- UUID.version: UUID的版本。1、4、3和5之间的任何值。
- UUID.is_safe: 了解UUID生成是否安全。我们将在本文的后半部分看到这一点。
让我们看看如何访问UUID的这些只读属性。
import uuid
UUID = uuid.uuid1()
print("UUID is ", UUID)
print("UUID Type is ",type(UUID))
print('UUID.bytes :', UUID.bytes)
print('UUID.bytes_le :', UUID.bytes_le)
print('UUID.hex :', UUID.hex)
print('UUID.int :', UUID.int)
print('UUID.urn :', UUID.urn)
print('UUID.variant :', UUID.variant)
print('UUID.version :', UUID.version)
print('UUID.fields :', UUID.fields)
print("Prining each field seperately")
print('UUID.time_low : ', UUID.time_low)
print('UUID.time_mid : ', UUID.time_mid)
print('UUID.time_hi_version : ', UUID.time_hi_version)
print('UUID.clock_seq_hi_variant: ', UUID.clock_seq_hi_variant)
print('UUID.clock_seq_low : ', UUID.clock_seq_low)
print('UUID.node : ', UUID.node)
print('UUID.time : ', UUID.time)
print('UUID.clock_seq : ', UUID.clock_seq)
print('UUID.SafeUUID : ', UUID.is_safe)
在Python中将UUID转换为字符串并将字符串转换为UUID
当我们调用 uuid.uuid1
UUID或任何其他版本的UUID时,您将获得UUID类的实例。当我们想要UUID字符串格式进行比较,操作或出于任何原因,我们可以使用str类获得其字符串表示形式。让我们看看如何将UUID更改为字符串。
import uuid
UUID1 = uuid.uuid1()
print("UUID of version 1 is ", UUID1)
# convert a UUID to a string of hex digits in standard form
print("UUID of version 1 in String format", str(UUID1))
您还可以获取不带破折号的UUID。例如,您需要使用字符串的replace方法从字符串中删除破折号。
import uuid
UUID1 = uuid.uuid1()
print("UUID of version 1 is ", UUID1)
# convert a UUID to a string of hex digits in standard form
uuidString = str(UUID1).replace("-", "")
print("UUID of version 1 in String removing dashes", uuidString)
现在让我们看看如何从字符串创建UUID
假设您收到了字符串格式的UUID。现在在您的应用程序中,您需要在UUID类实例中对其进行转换以进行某些操作。大号等看看如何使用一个 uuid.UUID
类来生成字符串有效的UUID。
的uuid.UUID
是,当我们通过UUID的参数,它返回一个UUID实例类。假设您具有字符串格式的UUID {018c168c-d509-11e8-b096-ccaf789d94a0}
。
import uuid
UUIDStrings = ["{55da37d1-d481-11e8-9013-adaf456d94a0}", "018c168c-d509-11e8-b096-ccaf789d94a0", "urn:uuid:e5e9394c-daed-498e-b9f3-69228b44fbfa"]
for string in UUIDStrings:
# make a UUID from a string of hex digits (braces and hyphens ignored)
myUUID = uuid.UUID(string)
print("My UUID is", myUUID)
print("My UUID time component is", myUUID.time)
print()
生成可复制的UUID
如何在Python中使用种子或现有UUID属性生成可复制的随机UUID?
要随时生成相同的UUID,您需要一个种子值。如上所述,UUID具有各种属性。使用其任何属性值,我们都可以再现相同的UUID。或者,您可以使用种子值生成相同的UUID。让我们来看看这两种方式。
您可以通过将参数值传递给uuid.UUID
类来创建UUID实例。例如,您可以从以下输入中创建UUID实例:–
- UUID.String
- UUID。字节
- UUID.Bytes_le
- UUID.Fields
- UUID.int
如果您具有上述任何一个值,那么可以生成一个UUID。让我们来看一个例子。我已经使用了所有相同UUID的值。因此,在所有情况下,结果都必须是相同的UUID。
import uuid
print("Generating UUID from int")
UUID_x = uuid.UUID(int=236357465324988601727440242910546465952)
print("UUID is", UUID_x)
print("UUID from URN")
UUID_x1 = uuid.UUID('urn:uuid:b1d0cac0-d50d-11e8-b57b-ccaf789d94a0')
print("UUID is", UUID_x1)
print("UUID from bytes")
UUID_x2 = uuid.UUID(bytes=b'\xb1\xd0\xca\xc0\xd5\r\x11\xe8\xb5{\xcc\xafx\x9d\x94\xa0')
print("UUID is", UUID_x2)
print("UUID from bytes_len")
UUID_x3 = uuid.UUID(bytes_le=b'\xc0\xca\xd0\xb1\r\xd5\xe8\x11\xb5{\xcc\xafx\x9d\x94\xa0')
print("UUID is", UUID_x3)
print("UUID from fields")
UUID_x4 = uuid.UUID(fields=(2983250624, 54541, 4584, 181, 123, 225054014936224))
print("UUID is", UUID_x4)
用种子复制UUID
出于测试目的,我们需要再次生成相同的UUID。再次,我在这里使用了faker模块作为种子值。
import uuid
from faker import Faker
fakerObj = Faker()
fakerObj.seed(8754)
print(fakerObj.uuid4())
fakerObj.seed(8754)
print(fakerObj.uuid4())
安全和不安全的UUID
您的uuid1可能会遇到隐私问题,因为它使用了主机的MAC地址。另一方面,uuid4()使用随机生成器创建UUID。
另外,uuid1也不安全,即uuid1()可能会也可能不会返回“安全”。当我们称之为安全时,必须使用同步方法生成UUID,以便没有两个进程可以获取相同的UUID。
生成安全的UUID取决于基础操作系统的支持。
Python 3.7在UUID类中添加了一个新属性,使用该属性可以确定UUID是安全还是不安全。现在,所有UUID实例都有一个is_safe 属性,该属性使我们知道UUID是否安全。
uuid.SafeUUID可以返回以下值。
- safe:** UUID是通过多处理安全方式生成的。
- unsafe: UUID不是以多处理安全方式生成的。
- unknown: 操作系统不提供有关是否已安全生成UUID的信息。
import uuid
UUID1 = uuid.uuid1()
print("uuid 1 safety", UUID1.is_safe)
来源:https://pynative.com/python-uuid-module-to-generate-universally-unique-identifiers/
翻译:freeaihub.com
建议使用PC或笔记本电脑,浏览器使用Chrome或FireFox进行浏览,以开启左侧互动实验区来提升学习效率,推荐使用的分辨率为1920x1080或更高。
我们坚信最好的学习是参与其中这一理念,并致力成为中文互联网上体验更好的学练一体的IT技术学习交流平台。

您可加QQ群:575806994,一起学习交流技术,反馈网站使用中遇到问题。
内容、课程、广告等相关合作请扫描右侧二维码添加好友。
狐狸教程 Copyright 2021