パスワードの強度
奥村先生のパスワード再考というエントリを読んで、パスワードの強度をビット長で表すプログラムをRubyで書いてみました。
# Base 2 logarithm module Math def self.log2(n) log(n) / log(2) end end # Bit length def password_strength_by_bits(ary, length) Math.log2(ary.length ** length) end lower = ('a'..'z').to_a upper = ('A'..'Z').to_a digit = ('0'..'9').to_a alpha = lower + upper alnum = lower + upper + digit p password_strength_by_bits(lower, 8) #=> 37.6035177451287 p password_strength_by_bits(alpha, 8) #=> 45.6035177451287 p password_strength_by_bits(alnum, 8) #=> 47.633570483095
まずMath.log2を作るとこから始めるのが渋いよね(←自分で言うな)。
底の変換を考えるのが面倒だったので、perldoc -f logを読んだのは内緒です。
追記:
奥村先生のエントリのコメント欄で出ていた問題。
1. 「英文字(52通り)6文字と、数字(10通り)2文字を使うこと」を条件にして作った8文字のパスワードのビット長を計算します。
まず、文字種の順序を考えずに(英文字6文字の後に数字2文字という順序に固定して考えるという意味)、パスワードの場合の数を計算すると、通りになる。次に8文字のどこを数字2文字にするかの組み合わせは通りになる。したがって、
p Math.log2((52 ** 6) * (10 ** 2) * 28) #=> 45.6538494206789
となります。
2. 「英文字(52通り)6文字と、英数字(62通り)2文字を使うこと」を条件にして作った8文字のパスワードのビット長を計算します。
このパスワードは、上記の1に加えて、英文字8文字のパスワードを加えた場合に相当します。英文字8文字のパスワードの場合の数は通りなので、
p Math.log2((52 ** 6) * (10 ** 2) * 28 + (52 ** 8)) #=> 46.6289030635486
となります。
まとめると…
英文字8文字 約45.6ビット 英文字6文字+数字2文字 約45.7ビット 英文字6文字+英数字2文字 約46.6ビット 英数字8文字 約47.6ビット
追記: