すべてのMongoDBドキュメントにGUID using uuid.uuid1()を割り当てています。次のように、11文字の一意で大文字と小文字を区別するYouTubeのようなIDを取得する方法が必要です
1_XmY09uRJ4
次のようなuuidの結果の16進数文字列から
ae0a0c98-f1e5-11e1-9t2b-1231381dac60
データベースに別の文字列を格納しなくても、短縮されたIDを16進数と動的に照合したり、その逆を動的に行うことができます。誰かがいくつかのサンプルコードを持っているか、これを行うことができるモジュールまたは式の方向に私を向けることができますか?
基になるバイトを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文字未満には決して適合しません。入力の3バイトごとに4文字が必要であり、すべての文字が6ビットの情報をエンコードします。
したがって、YouTubeの一意の文字列は完全な16バイトのUUIDに基づいていないため、それらの11文字のIDは、簡単に検索できるようにデータベースに格納され、より小さな値に基づいています。
あなたはPythonのbase64
モデル。 A GUIDは基本的に数値の16進数表現であり、ハイフンを削除して、16進数からデコードし、64進数にエンコードすることができます。逆に進むには、64進数からのデコードが必要です。ベース16でエンコードし、適切な場所にハイフンを挿入します。
URLセーフな方法でuuidを短縮する方法を特に探している人にとって、 @ MartijnPieters からの本当に有用な回答は base64
@ okoboko からの回答に関するコメントと同様に、URLセーフではない文字を処理するモジュール(いくつかの不要なビットなし)。
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}==')))