次の関数は私が数年前にとあるアプリケーションで、新規ユーザーの仮パスワードを生成する目的に使用していた。
import secrets
import string
def get_random_string(length):
secure_str = ''.join((secrets.choice(string.ascii_letters) for i in range(length)))
return secure_str
secretsモジュールを用いて、大文字と小文字からなる任意長の文字列をランダムに生成できる。
ところで、乱数を生成するPythonのモジュールといえば、secretsの他にrandomがある。
このモジュールの違いは使用する乱数発生アルゴリズムにあるが、アルゴリズムが異なると何が変わるのだろうか。
randomの乱数生成アルゴリズム
Mersenne Twisterという、乱数生成アルゴリズムである。
周期が$ {2^{19937}}-1 $と非常に長いが、決定論的(初期条件から結果が一意に定まる)であるため、初期値を知られると生成される乱数列が予測可能になってしまう。本来、生成される乱数は予測不可能であることが求められるため、この手法は特にセキュリティが重要な用途には適していない。
そのため、主にシミュレーション時の乱数として用いられる。
secretsの乱数生成アルゴリズム
OSが提供する乱数発生器を用いる。暗号論的擬似乱数生成器(CSPRNG)と言われており、暗号技術を要する用途に適している。
詳細は以下の資料を参照のこと。
また、この手法は暗号化のみならず、そのランダム性から並列同時実行されうる場面においても適している。
参考資料