如何在Python中创建GUID/UUID

1212

如何在 Python 中创建一个平台无关的 GUID/UUID?我听说有一种方法可以使用 Windows 上的 ActivePython,但它仅适用于 Windows,因为它使用了 COM。是否有一种方法可以使用纯 Python 实现?


5
http://docs.activestate.com/activepython/2.6/python/library/uuid.html - Sridhar Ratnakumar
82
为了一切神圣的爱,这是一个UUID - 通用唯一标识符http://en.wikipedia.org/wiki/Universally_unique_identifier - 只不过不幸的是微软更喜欢GUID。 - david.barkhuizen
14
这是一行代码:python -c 'import uuid; print(uuid.uuid4())' 它会生成一个UUID并将其打印出来。 - Ctrl-C
9
我认为GUID比UUID更有意义,因为 "global" 意味着在某个命名空间内是全球性的,而 "universal" 则似乎声称具有真正的全球唯一性。总之,我们都知道我们在谈论什么。 - duhaime
什么是GUID和UUID?为什么不创建一个唯一的哈希ID,例如https://dev59.com/HGAg5IYBdhLWcg3w9e_l? - Charlie Parker
同样的东西,大家。甚至RFC 4122都说UUID也被称为GUID。GUID这个词更容易发音,也更有趣。;-) - Darryl Wagoner WA1GON
8个回答

1486
uuid模块提供了不可变的UUID对象(UUID类)和函数uuid1()uuid3()uuid4()uuid5()用于生成符合RFC 4122规定的版本1、3、4和5的UUID。
如果你只需要一个唯一的ID,你应该调用`uuid1()`或`uuid4()`。
请注意,`uuid1()`可能会泄露隐私,因为它创建一个包含计算机网络地址的UUID。
`uuid4()`创建一个随机的UUID。
UUID版本6和7 - 用于现代应用程序和数据库的新的通用唯一标识符(UUID)格式 - 可以从以下链接获取:
- [rfc(草案)](draft):https://pypi.org/project/uuid6/ - [Python 2文档](draft):https://docs.python.org/2/library/uuid.html - [Python 3文档](draft):https://docs.python.org/3/library/uuid.html 示例(适用于Python 2和3):
>>> import uuid

>>> # make a random UUID
>>> uuid.uuid4()
UUID('bd65600d-8669-4903-8a14-af88203add38')

>>> # Convert a UUID to a string of hex digits in standard form
>>> str(uuid.uuid4())
'f50ec0b7-f960-400d-91f0-c42a6d44e3d0'

>>> # Convert a UUID to a 32-character hexadecimal string
>>> uuid.uuid4().hex
'9fe2c4e93f654fdbb24c02b15259716c'

53
请查看我写的 shortuuid 模块,它允许您生成更短、可读性更强的 UUID:https://github.com/stochastic-technologies/shortuuid - Stavros Korokithakis
4
@StavrosKorokithakis:你有没有为Python 3.x编写shortuuid模块? - Jay Patel
3
@JayPatel shortuuid是否不支持Python 3?如果是,请提交一个bug报告。 - Stavros Korokithakis
6
uuid4().hexstr(uuid4())之间的区别是前者返回UUID对象的16进制字符串表示,后者返回UUID对象的常规字符串表示。 - Kevin
17
如上所述,str(uuid4())返回包含破折号的UUID字符串表示形式,而uuid4().hex返回“UUID作为32字符十六进制字符串”的形式。 - stuartd

367
如果您使用的是Python 2.5或更高版本,则uuid模块已经包含在Python标准发行版中。
例如:
>>> import uuid
>>> uuid.uuid4()
UUID('5361a11b-615c-42bf-9bdb-e2c3790ada14')

31

我使用GUID作为数据库类型操作的随机键。

对我来说,带有破折号和额外字符的十六进制格式似乎过长。但是我也喜欢表示十六进制数字的字符串非常安全,因为它们不包含可能会在某些情况下引起问题的字符,例如'+'、'='等。

我使用了一个URL安全的base64字符串。但是以下内容不符合任何UUID/GUID规范(除了具有所需的随机性)。

import base64
import uuid

# get a UUID - URL safe, Base64
def get_a_uuid():
    r_uuid = base64.urlsafe_b64encode(uuid.uuid4().bytes)
    return r_uuid.replace('=', '')

4
如果你不打算在任何UUID上下文中使用它,那么你可以使用random.getrandbits(128).to_bytes(16, 'little')或(用于加密随机性)os.urandom(16),以获得完整的128位随机数(UUIDv4在版本信息上使用6-7位)。或者只使用15个字节(与UUIDv4相比,失去1-2位随机性),避免需要修剪掉“=”符号,并将编码大小减小到20个字节(从24个字节减小到22个字节),因为任何3个字节的倍数都可编码为#bytes / 3 * 4个base64字符,无需填充。 - ShadowRanger
@ShadowRanger 是的,基本上就是这个想法。128位随机比特,尽可能短,同时也要保证URL安全。理想情况下,它只使用大写和小写字母以及数字。所以我猜是一个62进制的字符串。 - Chris Dutrow
当我使用你的函数时,从return语句中得到一个类型错误,期望一个类似于字节的对象。可以通过return str(r_uuid).replace('=','')来修复它。 - Mark Kortink

14
如果您需要为模型或唯一字段传递UUID作为主键,则以下代码将返回UUID对象 -
 import uuid
 uuid.uuid4()
如果您需要将UUID作为URL参数传递,可以像下面的代码一样操作 -
import uuid
str(uuid.uuid4())

如果您想要获取 UUID 的十六进制值,可以执行下面的操作 -

import uuid    
uuid.uuid4().hex

3
如果您正在制作一个需要每次生成唯一 id 的网站或应用程序,那么 UUID 是 Python 中一个非常好的包,可以帮助创建唯一的 id。
**pip install uuid**

import uuid

def get_uuid_id():
    return str(uuid.uuid4())

print(get_uuid_id()) 

输出示例: 89e5b891-cf2c-4396-8d1c-49be7f2ee02d


1
运行以下命令:
pip install uuid uuid6

接下来你可以导入uuid1uuid3uuid4uuid5函数从uuid包中,以及uuid6uuid7函数从uuid6包中。

调用这些函数的示例输出如下(除了需要参数的uuid3uuid5):

>>> import uuid, uuid6
>>> print(*(str(i()) for i in [uuid.uuid1, uuid.uuid4, uuid6.uuid6, uuid6.uuid7]), sep="\n")
646e934b-f20c-11ec-ad9f-54a1500ef01b
560e2227-c738-41d9-ad5a-bbed6a3bc273
1ecf20b6-46e9-634b-9e48-b2b9e6010c57
01818aa2-ec45-74e8-1f85-9d74e4846897

1

2019年的答案(适用于Windows):

如果您想要一个在Windows上唯一标识机器的永久UUID,您可以使用这个技巧:(从我的回答https://dev59.com/YXE95IYBdhLWcg3wGZ9_#58416992中复制)。

from typing import Optional
import re
import subprocess
import uuid

def get_windows_uuid() -> Optional[uuid.UUID]:
    try:
        # Ask Windows for the device's permanent UUID. Throws if command missing/fails.
        txt = subprocess.check_output("wmic csproduct get uuid").decode()

        # Attempt to extract the UUID from the command's result.
        match = re.search(r"\bUUID\b[\s\r\n]+([^\s\r\n]+)", txt)
        if match is not None:
            txt = match.group(1)
            if txt is not None:
                # Remove the surrounding whitespace (newlines, space, etc)
                # and useless dashes etc, by only keeping hex (0-9 A-F) chars.
                txt = re.sub(r"[^0-9A-Fa-f]+", "", txt)

                # Ensure we have exactly 32 characters (16 bytes).
                if len(txt) == 32:
                    return uuid.UUID(txt)
    except:
        pass # Silence subprocess exception.

    return None

print(get_windows_uuid())

使用Windows API获取计算机的永久UUID,然后处理字符串以确保它是有效的UUID,最后返回一个Python对象(https://docs.python.org/3/library/uuid.html),该对象提供了方便的方法来使用数据(如128位整数、十六进制字符串等)。
祝你好运!
PS:subprocess调用可能可以直接用ctypes调用Windows内核/DLLs来替换。但对于我的目的而言,这个函数就足够了。它进行了强有力的验证并产生了正确的结果。

-6

这个函数是完全可配置的,它根据指定的格式生成唯一的uid

例如:- [8, 4, 4, 4, 12],这是指定的格式,它将生成以下uuid

LxoYNyXe-7hbQ-caJt-DSdU-PDAht56cMEWi

 import random as r

 def generate_uuid():
        random_string = ''
        random_str_seq = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
        uuid_format = [8, 4, 4, 4, 12]
        for n in uuid_format:
            for i in range(0,n):
                random_string += str(random_str_seq[r.randint(0, len(random_str_seq) - 1)])
            if n != 12:
                random_string += '-'
        return random_string

6
UUID是标准的,长度不可变。以可配置的方式生成随机字符串在某些情况下可能很有用,但在这种情况下并非如此。您可以查看https://zh.wikipedia.org/wiki/通用唯一识别码以获取定义。 - miguelr
7
最好避免使用此项,否则可能会遇到兼容性问题(这些不是标准 GUID)。 - Sylvain Gantois
3
同样,它远非保证是独一无二的。它可能是随机的,但并不独特。 - regretoverflow
2
@regretoverflow 没有GUID是绝对唯一的,仅仅是因为它们太庞大了,发生冲突的可能性极小。 - Austin Heller
1
GUID是一个非常长的数字的字符串表示,因此'LxoYNyXe...'并不足够。 - user2555515

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接