『Python数値計算ノート』ではアフィリエイトプログラムを利用して商品を紹介しています。

パスワード(暗証番号)生成関数

パスワード生成関数

何かの折にパスワードが必要な今日この頃ですね。私もつい先日、マイナンバーカードを受け取る時に、英数字が混在した6文字以上の暗証番号を考えて控え用紙に書き留めてくださいと言われました。でも、そんな時に慌てて暗証番号を決めてしまうと、覚えやすいようにと思って、つい自分の生年月日や出身地などを暗証番号に含めてしまうかもしれません。そうなると、やはりセキュリティの面で心配になってしまいますね。

最も安全な暗証番号は完全にランダムな文字列で構成された暗証番号です。とはいえ、ランダムな英数字なんて思いつきで書くのは大変ですよね。というわけで、Pythonでパスワード生成関数を実装して、いつでもちゃちゃっと暗証番号を用意できるようにしておきましょう!

数字パスワード生成関数

まずは練習として、数字だけの簡単なパスワード生成関数を実装してみます。

# In[1]

import string
import random

# 任意文字数の数字パスワード生成関数
# 引数(length)には取得したい文字数を渡す
# 戻り値は文字列の数字
def password_generator_n(length):
    numbers = string.digits  # (1)
    password = ''.join(random.choice(numbers) for _ in range(length))  # (2)
    return password

(1) では標準ライブラリにある String モジュールの digits 属性を利用して、0 から 9 まで並んだ文字列 ‘0123456789’ を用意しています。そこから (2) のコードで必要な回数だけランダムに取り出してつなげています。
 
それでは、試しに 4 文字のパスワードを生成してみましょう。

# In[2]

# 乱数シードの初期化
random.seed(101)  # (3)

# 4文字の数字パスワードを生成
pw = password_generator_n(4)
print(pw)

# 9385

皆さんと実行結果を一致させるために、コード (3) で乱数シードを与えていますが、実際に使う時はこの部分を削除してください。

数字と小文字英字のパスワード生成関数

さて、次は数字と小文字アルファベットが混在したパスワードを生成する関数を実装してみます。

# In[3]

# 任意文字数の数字と小文字英語パスワード生成関数
def password_generator_nl(length):
    characters = string.digits + string.ascii_lowercase
    password = ''.join(random.choice(characters) for _ in range(length))
    return password

random.seed(102)  # 実際に使う時はこの部分をコメントアウト

# 12文字の数字と小文字英語のパスワードを生成
pw = password_generator_nl(12)
print(pw)

# 9mazboir2xyx

小文字アルファベットは string.ascii_lowercase で得ています。もし、大文字アルファベットにしたい場合は、この部分を string.ascii_uppercase にしてください。

汎用パスワード生成関数

それでは最後に、ユーザーが使う文字の種類を選択できるパスワード生成を実装してみます。

# In[4]

def password_generator(length, digits=True, lower=False, upper=False):

    # オプション引数を数値(0または1)に変換
    optional_argument = [int(x) for x in [digits, lower, upper]]  # (4)

    # パスワードに使用する文字列の種類
    optional_string = [string.digits, string.ascii_lowercase, string.ascii_uppercase]  # (5)

    idx = 0
    characters = ""

    for _ in range(3):
        if optional_argument[idx]:
            characters += optional_string[idx]
        idx += 1

    password = ''.join(random.choice(characters) for _ in range(length))
    return password

パスワードの長さを決める length 以外はすべてオプション引数としています。たとえば、digit=True, lower=False, upper=True とすると、数字と大文字アルファベットが混在したパスワードを返します。
 
コードの中身が少し難しいかもしれないので解説しておきます。(4) ではリスト内包表記を使って、関数が受け取ったオプション引数を int() で数値に変換しています。0 は False、1 は True に対応します。このリストは (5) で作成した各種文字列(数字、小文字、大文字)のリストに対応するインデックスとして使用します。以下、for 構文でユーザーが選択した種類の文字列だけ文字セットに加えています。
 
試しに、数字と大文字アルファベットで構成される12文字のパスワードを生成してみましょう。

# In[5]

random.seed(103)  # 実際に使う時はこの部分をコメントアウト

# 数字と大文字アルファベットで構成される12文字のパスワード
pw = password_generator(12, lower=False, upper=True)

print(pw)
# TD47OTL7V58E

コメント