module PasswordGenerate

Constants

ALPHA

no Ii Ll Oo 0 1

NUM
SYMBOL

Public Class Methods

fill(password, bit, spots, pos, key = nil) click to toggle source
# File lib/password_generate.rb, line 106
def self.fill password, bit, spots, pos, key = nil
  password[pos] = bit
  spots.delete_at key unless key == nil
end
generate(mode = nil, length = nil) click to toggle source
# File lib/password_generate.rb, line 36
def self.generate mode = nil, length = nil

  ## normalize args

  mode = case mode.to_s[0]
         when 'm' then 'mixed'
         when 'a' then 'alphanum'
         when 'n' then 'num'
         else 'mixed'
         end

  length = 12 unless length.is_number?
  length = 3 if length.to_i < 3
  length = length.to_i

  pool = case mode
         when 'num' then NUM
         when 'alphanum' then ALPHA + NUM
         when 'mixed' then SYMBOL + ALPHA + NUM
         end

  ## fill in password places

  password = {}
  spots = (0..length-1).to_a

  # first select a random non-first place to put a symbol in
  if mode == 'mixed'
    bit = pick SYMBOL
    key = pick (0..spots.size-1).to_a
    pos = spots[key]
    pos = 1 if pos == 0
    fill password, bit, spots, pos, key
  end

  # put first as alpha
  if mode == 'alphanum' || mode == 'mixed'
    bit = pick ALPHA
    fill password, bit, spots, 0, 0
  end

  # ensure at least one num present
  bit = pick NUM
  key = pick (0..spots.size-1).to_a
  pos = spots[key]
  fill password, bit, spots, pos, key

  # fill remaining
  spots.each do |v|
    # disallow adjacent same char
    loop do
      bit = pick pool
      break if v == 0 || bit != password[v-1]
    end

    fill password, bit, spots, v
  end

  ## format password into a string

  password.sort.map { |v| v[1] }.join('')
end
pick(pool) click to toggle source
# File lib/password_generate.rb, line 99
def self.pick pool
  v = nil
  v = pool.split('').sample if pool.respond_to? :split
  v = pool.sample if pool.respond_to? :sample
  v
end