Skip to content

Instantly share code, notes, and snippets.

@nkwhr
Created July 15, 2015 08:17
Show Gist options
  • Save nkwhr/de6faa899c97490ec461 to your computer and use it in GitHub Desktop.
Save nkwhr/de6faa899c97490ec461 to your computer and use it in GitHub Desktop.
# ・8-18文字であること
# ・大文字小文字アルファベットと数字が含まれていること
# ・.@_- (ドット、アットマーク、アンダースコア、ハイフン)のうち少なくとも1
# つ含まれていること
class PasswordGeneratorAttributeError < StandardError; end
class PasswordGenerator
NUMBERS = [*0..9]
UPPER_CHARS = [*'A'..'Z']
LOWER_CHARS = [*'a'..'z']
SYMBOLS = ['.', '@', '_', '-']
MAX_LENGTH = 18
MIN_LENGTH = 8
attr_accessor :length, :max_syms, :max_nums
def initialize(length = 8)
@length = length
if length < MIN_LENGTH || length > MAX_LENGTH
raise PasswordGeneratorAttributeError,
"Password length should be in between #{MIN_LENGTH} and #{MAX_LENGTH}."
end
@max_syms = (length * 0.25).to_i
@max_nums = (length * 0.25).to_i
end
def self.new_password(length)
new(length).generate
end
def generate
(SYMBOLS.sample(sym_length) +
NUMBERS.sample(num_length) +
UPPER_CHARS.sample(upper_char_length) +
LOWER_CHARS.sample(lower_char_length)
).shuffle.join
end
private
def sym_length
if length - 3 < max_syms
raise PasswordGeneratorAttributeError, 'max_syms too long'
end
@sym_length ||= rand(max_syms - 1) + 1
end
def num_length
if length - 3 < max_nums
raise PasswordGeneratorAttributeError, 'max_nums too long'
end
@num_length ||= rand(max_nums - 1) + 1
end
def upper_char_length
if length - 2 < max_syms + max_nums
raise PasswordGeneratorAttributeError, 'max_syms + max_nums too long'
end
length_left = length - sym_length - num_length
@upper_char_length ||= length_left - (rand(length_left - 2) + 1)
end
def lower_char_length
@lower_char_length ||= length - sym_length - num_length - upper_char_length
end
end
pass = PasswordGenerator.new_password(8)
p pass
# => "EbVG7.Nq"
# or
pwgen = PasswordGenerator.new
pwgen.length = 10
pwgen.max_syms = 4
pwgen.max_nums = 4
p pwgen.generate
#=> "D-TH4q@_Gf"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment