テーブル内の主キーの英数字の一意のIDを生成する非常に迅速な方法を探しています。
このようなものは機能しますか?
def genKey():
hash = hashlib.md5(RANDOM_NUMBER).digest().encode("base64")
alnum_hash = re.sub(r'[^a-zA-Z0-9]', "", hash)
return alnum_hash[:16]
乱数を生成する良い方法は何でしょうか?マイクロタイムに基づいている場合、異なるインスタンスから同時に複数のgenKey()を呼び出す可能性を考慮する必要があります。
または、これをすべて行うより良い方法はありますか?
答えはどれも、文字0-9、a-z、A-Zで構成されるランダムな文字列を提供しないため、次のいずれかを提供する実用的なソリューションがあります。 4.5231285 e + 74キー:
import random, string
x = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(16))
print(x)
また、ASCIIコードを暗記することなく、非常に読みやすくなっています。
python 3.6.2
以来、さらに短いバージョンがあります。
import random, string
x = ''.join(random.choices(string.ascii_letters + string.digits, k=16))
print(x)
これを使用できます:
>>> import random
>>> ''.join(random.choice('0123456789ABCDEF') for i in range(16))
'E2C6B2E19E4A7777'
生成されたキーが一意であるという保証はないため、元の挿入が失敗した場合に新しいキーで再試行する準備ができている必要があります。また、一意性を保証するために、ランダムな値を使用する代わりに、決定論的アルゴリズムを使用して自動インクリメントIDから文字列を生成することを検討することもできます(ただし、予測可能なキーも提供します)。
id module (Python 2.5+)をご覧ください。
簡単な例:
>>> import uuid
>>> uid = uuid.uuid4()
>>> uid.hex
'df008b2e24f947b1b873c94d8a3f2201'
OPは16文字の英数字文字列を要求しましたが、UUID4文字列は32文字の長さであることに注意してください。この文字列を切り捨てるのではなく、完全な32文字を使用してください。
乱数の場合、適切なソースはos.urandom
:
>> import os
>> import hashlib
>> random_data = os.urandom(128)
>> hashlib.md5(random_data).hexdigest()[:16]
2016年12月にリリースされたPython 3.6では、secrets
モジュールが導入されました。
この方法でランダムトークンを生成できるようになりました。
import secrets
secrets.token_hex(16)
Python docsから:
secrets
モジュールは、パスワード、アカウント認証、セキュリティトークン、および関連する秘密などのデータの管理に適した暗号的に強力な乱数を生成するために使用されます。特に、
secrets
は、セキュリティや暗号化ではなく、モデリングとシミュレーション用に設計されたrandom
モジュールのデフォルトの擬似乱数ジェネレーターよりも優先して使用する必要があります。
>>> import random
>>> ''.join(random.sample(map(chr, range(48, 57) + range(65, 90) + range(97, 122)), 16))
'CDh0geq3NpKtcXfP'
この値は、呼び出しごとに1ずつ増加します(折り返します)。値を保存する最適な場所を決定する方法は、使用方法によって異なります。 this 興味の説明があります。これは、Guidがどのように機能するかだけでなく、より小さくする方法についても説明しているためです。
簡単な答えは次のとおりです。これらの文字の一部をタイムスタンプとして使用し、他の文字を「Uniquifier」として使用します。値は、uidジェネレーターの呼び出しごとに1ずつ増加します。
python inbuilt idを使用するだけです:
import uuid
print uuid.uuid4().hex[:16].upper()