目次:
まえがき
この記事ではGUIのインターフェースから各種条件を受け取ってパスワードを実際に生成するクラスを実装を取り上げていく、そんな素敵な記事なんです。
全体の機能をちょっと整理すると以下の3つに分けられる。
- GUIインターフェース:ビュー
- GUIとのやり取り:コントローラー
- パスワード生成クラス:コントローラーから値もらう
GUI部分は今後記事にしていくが、QMLとPySideとで繋がり具合を調べていてふと、「そういえばパスワードそのものを生成する機能ってふわっとしたイメージしかないな」と思い、なんやかんやでこちらを先に完成させることになった。
変更履歴
2020/04/05: 新規作成
この記事の環境
バージョン: Python 3.8.1
IDE: Spacemacs
環境構築: pyenv、pyenv-virtualenv
OS: macOS
パスワード生成クラスの作成
まずパスワード生成クラスの機能の詳細を明らかにしたい。今回は生成機能を1つのクラスにする。シンプルな機能なのでPySide2を使うコントローラー役の内部に書いても良かったが、これも勉強とゆうことでできるだけ多くの言語機能を使うことにした。
機能詳細
パスワード生成の条件は4種類。3つは複数の選択肢のうち1つのみ選択可能だが、残り1つは重複して選択できる。
- 文字数
- 文字の始まりの指定
- 形式指定
- 含める文字種類(重複可)
この4つの指定を受け取りパスワードを生成して文字列として返す。
今回やったこと
- 生成クラスと定数クラスの2つを作った。
- DocstringをNumPyスタイルで記述した。
- パッケージ管理用の特殊変数も使ったよ。
(__version__, __autor__)
- お決まりの
__name__ == "main"
を使ったよ。 - 定数クラスを作ってインポートしただよ。
パスワード生成モジュール:ソースコード
__version__, __author__
などはPythonのライブラリに入っているので真似して入れてみた。ただsetup.py
なるものがあるとモジュールに__version__
を書く必要はないのかもしれない。
まだまだ改良の余地、修正の余地があるがとりあえずこんなもんでいいだろう。
# -*- coding: utf-8 -*- """\ パスワード生成モジュール 英字(大文字、小文字)、記号、数字の中から抽出。 条件は、文字数、含める文字種、始まりの文字指定、パスワード形式指定 """ __version__ = "0.1" __author__ = "Hideo Tsujisaki" import random import string import constants as const class PwRandomizer(object): """\ パスワード生成機能。 英字(大文字、小文字)、記号、数字の中から抽出。 条件は、文字数、含める文字種、始まりの文字指定、パスワード形式指定。 Attributes ---------- char_lim : integer condition : string start_con : string style : string, default None Rturns ------ pass_word : string """ const.START_COND_MOJI = "moji" const.START_COND_KIGO = "kigo" const.START_COND_NUMB = "numb" const.PASSWORD_STYLE_HYPHEN = "pyhe" const.PASSWORD_STYLE_DOTTS = "dott" cond = "" def __init__(self, char_lim, condition, start_con, style=None): self.lower_case = string.ascii_lowercase self.upper_case = string.ascii_uppercase self.digits = string.digits self.kigou = string.punctuation self.char_lim = char_lim self.condition = condition self.staert_con = start_con self.style = style self.pw_builder() if __name__ == "main": def pw_builder(self): self.cond_setter() # パスワード生成部 pass_word = "" if self.s_con == const.TART_COND_MOJI: pass_word += random.choise(self.lower_case) if self.s_con == const.START_COND_KIGO: pass_word += random.coise(self.kigou) if self.s_con == const.START_COND_NUMB: pass_word += random.choice(self.digits) build_counter = 2 for build_counter in range(self.num): pass_word += random.choice(self.cond) # パスワード整形部 cep_type = "" if self.styles == const.PASSWORD_STYLE_HYPHEN: cep_type = "-" if self.styles == const.PASSWORD_STYLE_DOTTS: cep_type = "." if self.styles is not None: if self.num == 8: pass_word.replace(pass_word[2], cep_type) pass_word.replace(pass_word[5], cep_type) if self.num == 16: pass_word.replace(pass_word[7], cep_type) pass_word.replace(pass_word[12], cep_type) if self.num == 32: pass_word.replace(pass_word[9], cep_type) pass_word.replace(pass_word[16], cep_type) pass_word.replace(pass_word[23], cep_type) pass_word.replace(pass_word[30], cep_type) return pass_word def cond_setter(self): """\ 含める文字の設定(複数同時指定可能) Return: String ex."ab", "ac" condition: 大文字=a、記号=b、数字=c """ cond = self.lower_case if "a" in self.condition: cond += self.upper_case if "b" in self.condition: cond += self.kigou if "c" in self.condition: cond += self.digits
定数モジュール:ソースコード
Pythonには定数が言語機能として実装されていないということで、定数クラスを作ろうと思った。最初は定数クラスに値を入れてタプルとしてあればいいかと思った。しかし少し調べてみるともっと良い方法が見つかったのでこれにした。
使う側で変数を定義して使うが、1度値を代入すると2回目以降は代入できない。エラーが出る。まさに定数。ほぼマルパクリ。パクリもと。
# -*- coding: utf-8 -*- """\ 定数モジュール """ __version__ = "0.1" __author__ = "Hideo Tsujisaki" class _Constants(object): class ConstError(TypeError): pass def __repr__(self): return "定数型の定義。" def __setattr__(self, const_name, value): if const_name in self.__dict__: raise self.ConstError("定数には再代入できません。 (%s)" % const_name) self.__dict__[const_name] = value def __del__(self): self.__dict__.clear()
むすび
とりあえずこんなところでよしとして次はPySide2を使ったコントローラーとQMLもビューを完成させたい。最終的な動作テストをした後で色々と仕様変更なり修正なりがあるだろうから完成品まではままだ時間がかかると思われる。
コメント