問題文
[2/12/2012] Challenge #4 [easy] : dailyprogrammer
ランダムパスワードジェネレータを作りましょう!
解答
まず候補となる文字を用意しよう。
問題文リンク先の、トップバッターの解答者のように、
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
とベタに用意してあげてもいいけど、こういう文字列をいちいち打ち込むのも面倒。
なのでこいつもASCIIコード表から生成してみよう。
'A'から'Z'まで文字コードはアルファベット順で連続していることが分かる。
よって、
range(ord('A'), ord('Z')+1) # ASCIIコード表と見比べてみる。 # => [65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90]
で'A'から'Z'までのコードを取得できる。
これにchrを適用して、それぞれの数値に対応する文字に戻してあげると、'A'から'Z'までの配列が取得できる。
map(chr, range(ord('A'), ord('Z')+1)) # => ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
'a'から'z'、'0'から'9'までの文字についても同様に生成できる。
map(chr, range(ord('a'), ord('z'+1)) # => ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'] map(chr, range(ord('0'), ord('9'+1)) # => ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
まとめるとこうなる。
alphabets = [] codes = (('a', 'z'), ('A', 'Z'), ('0', '9')) for r in codes: chars = map(chr, range(ord(r[0]), ord(r[1])+1)) alphabets.extend(chars)
これでパスワード生成に必要な文字は揃った。
つづいてこれをランダムに適当な回数だけ取り出して配列を作る。
import random length = random.randint(*(8, 13)) # 8から13文字のパスワード password = [random.choice(alphabets) for _ in range(length)] # => ['l', 'J', 'i', 'd', 'b', 'H', 'M', 'A', 'P', '5', 'y']
あとはこの配列を"".joinすることによって文字列化できる。これでパスワード生成プログラムは完成!
password = "".join(password) # => lJidbHMAP5y
適当にraw_inputまたはsys.argvを使うなりすればユーティリティとして使えると思います。