转换UUID 32个字符的十六进制字符串为“YouTube的风格的”短ID和回

问题描述 投票:27回答:3

我使用uuid.uuid1指派我所有的MongoDB文档的GUID()。我想办法,我可以得到11个字符,独特的,区分大小写类似YouTube的ID,如

1_XmY09uRJ4 

从UUID的产生的十六进制字符串,它看起来像

ae0a0c98-f1e5-11e1-9t2b-1231381dac60

我希望能够匹配缩短ID为十六进制,反之亦然,动态,而不必存储在数据库中另一个字符串。任何人都不会有一些示例代码,也可以点我的模块或配方,能做到这一点的方向是什么?

python guid uuid
3个回答
50
投票

转换的基本字节到Base64值,剥离=填充和换行。

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

>>> import uuid, base64
>>> base64.urlsafe_b64encode(uuid.uuid1().bytes).rstrip(b'=').decode('ascii')
'81CMD_bOEeGbPwAjMtYnhg'

相反:

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

为了把它转换成通用的功能:

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 + '==')))

这使您能够代表一个更紧凑的形式在16个字节的UUID的方法。压缩任何进一步和你失去的信息,这意味着你不能再解压充分UUID。该16个字节可以代表值的全范围永远不会适合它任何小于22个的base64字符,需要4个字符每三个字节的输入和每个字符编码信息的6位。

YouTube的唯一的字符串因此不是基于完整的16字节的UUID,他们的性格11个IDS很可能存储在数据库中,便于查找和基于较小的值。


1
投票

你可以看看Python的base64模型。 GUID是本质上是一个数字的基-16表示,你可以修剪出的连字号,解码从基座16,并编码成底部64将在相反的要求从基座64,编码解码在基座16,以及将所述连字符在合适的地方。


0
投票

对于那些专门针对一种方法来缩短URL中的安全方式的UUID看,从@MartijnPieters真正有用的答案可以部分使用base64模块来处理未URL的安全类似于从@okoboko这个答案的注释字符(不被简化一些不必要的比特)。

import base64
import uuid

# uuid to b64 string and back
uuid_to_b64str = base64.urlsafe_b64encode(uuid.uuid1().bytes).decode('utf8').rstrip('=\n')
b64str_to_uuid = uuid.UUID(bytes=base64.urlsafe_b64decode(f'{uuid_to_b64str}=='))

# uuid string to b64 string and back
uuidstr_to_b64str = base64.urlsafe_b64encode(uuid.UUID(str(uuid.uuid1())).bytes).decode('utf8').rstrip('=\n')
b64str_to_uuidstr = str(uuid.UUID(bytes=base64.urlsafe_b64decode(f'{uuidstr_to_b64str}==')))
© www.soinside.com 2019 - 2024. All rights reserved.