PythonのUUIDは、特殊文字として表現しました
-
21-09-2019 - |
質問
PythonでUUIDを作成する場合は、likesoます:
>>> uuid.uuid1()
UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
どのようにできた1つの大文字のアルファベットAZマイナス文字D、F、I、O、Q、およびU、プラス桁の数字からなる文字列にUUIDマップ、プラス文字「+」と「=」 。すなわち、図32(比較的OCR優しい)文字の組への整数または文字列から
[ABCEGHJKLMNPRSTVWXYZ1234567890+=]
私は(OCR友好のために)OCRf
セットこれを呼ぶことにします。
私は同型の機能を持っているしたいと思います:
def uuid_to_ocr_friendly_chars(uid)
"""takes uid, an integer, and transposes it into a string made
of the the OCRf set
"""
...
私が最初に考えたのは32例えばをベースにUUIDを変更するプロセスを通過することです。
OCRf = "ABCEGHJKLMNPRSTVWXYZ1234567890+="
def uuid_to_ocr_friendly_chars(uid):
ocfstr = ''
while uid > 1:
ocfstr += OCRf[uid % 32]
uid /= 32
return ocfstr
しかし、私はこの方法では、この変換について移動する最善かつ最速の方法ですかどうかを知りたいのですが - あるいは単純かつ高速の方法(例えば組み込み、よりスマートなアルゴリズム、または単により良い方法)があるかどう。
私はあなたの入力を感謝しています。ありがとうございます。
解決
これは、32〜26文字から、「スクイーズ」18.75パーセントによる表現、すなわちにあなたにどのように重要なのですか? 、バイトのこの小さな割合を保存する場合は、絶対に重要ではないので、uid.hex.upper().replace('D','Z')
のようなものは、あなたが(あなたが利用できるように全体のアルファベットを使用しますが、これの唯一のコストは18.75パーセントが「絞り」という欠けているではない)聞いて何を行います。
すべての最後のバイトを下に絞ることは非常に重要であるならば、私は20ビットごとの部分文字列で作業したい - それは5進文字、あなたのファンキーなアルファベットの4つの文字です。これらの6(手の込んだ何もして得るために何もないので、あなたが上記のようhex.upper().replace
を取ることができたために残さプラス8ビットは、)があります。あなたは簡単に.hex
をスライスして部分文字列を取得し、int(theslice, 16)
でint型にそれぞれを変えることができます。その後、あなたは基本的には上記の使用している同じアルゴリズムを適用することができます - しかし、算術はすべて大いに少ない数で行われるので、速度ゲインは、材料にする必要があります。また、+=
にループすることにより、文字列を構築していない - すべての「数字」のリストを作成し、最後にそれらをすべて''.join
- 。それはまた、パフォーマンスの改善です。
他のヒント
>>> OCRf = 'ABCEGHJKLMNPRSTVWXYZ1234567890+='
>>> uuid = 'a8098c1a-f86e-11da-bd1a-00112444be1e'
>>> binstr = bin(int(uuid.replace("-",""),16))[2:].zfill(130)
>>> ocfstr = "".join(OCRf[int(binstr[i:i+5],2)] for i in range(0,130,5))
>>> ocfstr
'HLBJJB2+ETCKSP7JWACGYGMVW+'
再度変換するには、
>>> "%x"%(int("".join(bin(OCRf.index(i))[2:].zfill(5) for i in ocfstr),2))
'a8098c1af86e11dabd1a00112444be1e'
transtbl = string.maketrans(
'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
'ABCEGHJKLMNPRSTVWXYZ1234567890+='
)
uuidstr = uuid.uuid1()
print base64.b32encode(str(uuidstr).replace('-', '').decode('hex')).rstrip('=').translate(transtbl)
はい、この方法は、のの、私は少し病気に尋ねるための感謝を作るんます。