2007-07-04 明日は会社お休みしちゃいます。
パスワード生成スクリプトをきっかけにoptparseを使ってみました
会社ではPerlで使い捨てスクリプトを書いたり、書かなかったりしているbonlifeです。id:nullpobugさんのパスワード生成スクリプトを参考にさせていただき、Pythonの標準モジュール「optparse」を使うサンプルを書いてみました。使い慣れておいて、ちょっとしたツールを作る時にサッと使いたいところですね。ということで、早速スクリプトです。(色々と追記してしまったので、ちょっとだけ長めです。)
- gen_passwd.py
import sys import string import random from optparse import OptionParser allowed_chars = (string.letters + string.digits).translate(string.maketrans('',''),'lO0') def gen_pass_core(passlen): password = '' for i in range(passlen): password += allowed_chars[random.randrange(len(allowed_chars))] return password def gen_pass(passlen,strong): if strong: if passlen < 3: raise Exception, 'password length should be larger than 3' while True: password = gen_pass_core(passlen) if (password.isalpha() == False and password.isdigit() == False and password.isupper() == False and password.islower() == False): return password break else: return gen_pass_core(passlen) def main(): usage = "usage: %prog [options] length count" version = "%prog 1.0" parser = OptionParser(usage=usage,version=version) parser.add_option("-s","--strong",action="store_true",dest="strong",help="generate strong password") (options, args) = parser.parse_args() if len(args) != 2: parser.print_help() exit() passlen = int(args[0]) count = int(args[1]) for i in range(count): print gen_pass(passlen,options.strong) if __name__ == "__main__": main()
少しだけ説明です。
まず、パスワードに使える文字列の生成です。文字列リテラルで直接定義しても全く問題ないのですが、Pythonクックブックの1章を読んで覚えたてのstringモジュールの定数などを使ってみました。translateを使って指定した文字列を削除したり。
続いて、本題のoptparse。何かしらoptionを定義しないとつまらないので、引数を取らない -s (--strong) というオプションを付けてみることにしました。
parser.add_option("-s","--strong",action="store_true",dest="strong",help="generate strong password")
(options, args) = parser.parse_args()
上記のようにすると、-s あるいは --strong が指定された場合に、action の store_true が効いて、options.strong が True になります。これを利用して、gen_pass() の部分で強制的にstrongなパスワードにするかどうかを制御します。(help で指定した文字列は、引数に -h あるいは --help が指定された場合に使われます。)
次は、strong を強制する場合の処理について説明します。
if (password.isalpha() == False and
password.isdigit() == False and
password.isupper() == False and
password.islower() == False):
return password
見ていただければ分かると思いますが、アルファベットのみではなく、数字のみでもなく、大文字のみでもなく、小文字のみでもない場合に、はじめてreturnしています。(これで本当にstrongか、というのは気にしない方向で。あくまでもオプションを指定する練習です。) この条件に当てはまるまで、外側の while ループで何度も繰り返しています。この処理を追加した結果、パスワード文字列が3文字以上でなければ、passwordがreturnされず、永遠にループされてしまうことになりました。そこで、以下のように例外を発生させることに。
if strong:
if passlen < 3:
raise Exception, 'password length should be larger than 3'
本当は、Exceptionクラスを継承した独自の例外クラスを定義して、その例外をraiseした方が良いのかもしれませんが、今回はとりあえず止まれば良いや、的な発想で、素のExceptionを使ってみました。
そんなこんなで完成したスクリプトの使い方は以下の通りです。
C:\test\python>python gen_passwd.py --version gen_passwd.py 1.0
C:\test\python>python gen_passwd.py 8 3 whbRu5he gcZCtrHT BEvFZfAd
C:\test\python>python gen_passwd.py -s 8 3 ExY3WXwm r8xyacH4 V66WGn6R
C:\test\python>python gen_passwd.py -s 2 3
Traceback (most recent call last):
File "gen_passwd.py", line 48, in <module>
main()
File "gen_passwd.py", line 45, in main
print gen_pass(passlen,options.strong)
File "gen_passwd.py", line 17, in gen_pass
raise Exception, 'password length should be larger than 3'
Exception: password length should be larger than 3
毎日Pythonに触れていると、少しずつ手に馴染んでくる気がする今日この頃です。
- 7 http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4GGIH_jaJP210JP211&q=SE 年収
- 6 http://reader.livedoor.com/reader/
- 5 http://d.hatena.ne.jp/nullpobug/
- 4 http://search.yahoo.co.jp/search?p=ファイルを閉じる VBA excel&ei=UTF-8&fr=top_v2&x=wrt
- 4 http://www.google.co.jp/ig?hl=ja
- 3 http://d.hatena.ne.jp/keyworddiary/Perl?date=20070704
- 3 http://search.yahoo.co.jp/search?p=apogee ライブ&fr=top_v2&tid=top_v2&ei=euc-jp&search.x=1
- 3 http://search.yahoo.co.jp/search?p=ミートザワールドビート+2007&rs=0&tid=top_v2&ei=UTF-8&search_x=1&fr=top_v2&yuragi=off
- 3 http://search.yahoo.co.jp/search?p=SWEET+LOVE+SHOWER&fr=top_v2&tid=top_v2&ei=euc-jp&search.x=1&x=26&y=6
- 3 http://www.google.com/reader/view/
![Ringo EXPO 08 [DVD] Ringo EXPO 08 [DVD]](http://ecx.images-amazon.com/images/I/413tH0m3YGL._SL75_.jpg)








