将UUID 32个字符的十六进制字符串转换为"YouTube风格"的短ID并返回

zak*_*ces 28 python uuid guid

我正在使用uuid.uuid1()为我的所有MongoDB文档分配一个GUID.我想要一种方法,我可以得到一个11个字符,独特,区分大小写的类似YouTube的ID,例如

1_XmY09uRJ4 
Run Code Online (Sandbox Code Playgroud)

从uuid得到的十六进制字符串看起来像

ae0a0c98-f1e5-11e1-9t2b-1231381dac60
Run Code Online (Sandbox Code Playgroud)

我希望能够将缩短的ID与十六进制匹配,反之亦然,而无需在数据库中存储另一个字符串.有没有人有一些示例代码或可以指向我可以做到这一点的模块或公式的方向?

Mar*_*ers 52

将基础字节转换为base64值,剥离=填充和换行符.

你可能想使用的base64.urlsafe_b64encode()功能,以避免使用/+(_-被代替),这样得到的字符串可以作为一个URL路径元素:

>>> import uuid, base64
>>> base64.urlsafe_b64encode(uuid.uuid1().bytes).rstrip(b'=').decode('ascii')
'81CMD_bOEeGbPwAjMtYnhg'
Run Code Online (Sandbox Code Playgroud)

相反:

>>> uuid.UUID(bytes=base64.urlsafe_b64decode('81CMD_bOEeGbPwAjMtYnhg' + '=='))
UUID('f3508c0f-f6ce-11e1-9b3f-002332d62786')
Run Code Online (Sandbox Code Playgroud)

将其转换为通用函数:

from base64 import urlsafe_b64decode, urlsafe_b64encode
from uuid import UUID

def uuid2slug(uuidstring):
    return urlsafe_b64encode(UUID(uuidstring).bytes).rstrip(b'=').decode('ascii')

def slug2uuid(slug):
    return str(uuid.UUID(bytes=urlsafe_b64decode(slug + '==')))
Run Code Online (Sandbox Code Playgroud)

这为您提供了一种以更紧凑的形式表示16字节UUID的方法.进一步压缩并丢失信息,这意味着您无法再将其解压缩到完整的UUID.

因此,YouTube的唯一字符串不是基于完整的16字节UUID,它们的11个字符ID可能存储在数据库中,以便于查找并基于较小的值.