class Part

Class representing a password plan part, which map to installed part lists

Constants

LEET

Public Class Methods

absences() click to toggle source
# File lib/oro/parts.rb, line 53
def self.absences
  length_exists = proc { |length| list.select { |w| w.length == length }.empty? ? false : true }
  lengths = []
  (shortest..longest).each do |len|
    lengths << len if !length_exists.call(len)
  end
  lengths
end
contiguous?() click to toggle source
# File lib/oro/parts.rb, line 49
def self.contiguous?
  absences.empty?
end
count() click to toggle source
# File lib/oro/parts.rb, line 25
def self.count
  list.size
end
descendants() click to toggle source
# File lib/oro/parts.rb, line 45
def self.descendants
  ObjectSpace.each_object(Class).select { |klass| klass < self }
end
distinct?() click to toggle source
# File lib/oro/parts.rb, line 41
def self.distinct?
  list.size == list.uniq.size ? true : false
end
get(size, config = {}) click to toggle source
# File lib/oro/parts.rb, line 66
def self.get(size, config = {})
  single_character_list? ? get_for_single_character_part(size, config) : get_for_word_part(size, config)
end
get_for_single_character_part(size, config) click to toggle source
# File lib/oro/parts.rb, line 70
def self.get_for_single_character_part(size, config)
  result = []
  size.times { result << get_one }
  result.first.capitalize! if config[:capitalize]
  result[rand(result.length)].upcase! if config[:capitalize_random]
  result.join
end
get_for_word_part(size, config = {}) click to toggle source
# File lib/oro/parts.rb, line 78
def self.get_for_word_part(size, config = {})
  fail MatchlessLengthWordError, "Matchless length of #{size} requested from:\n#{self}" if size < shortest || size > longest

  # FIXME: The performance benefit of refactoring to use Array#reject, or possibly reject!, should be tested.
  get_proc, attempt = proc { get_one }, ''

  until attempt.length == size do attempt = get_proc.call end

  attempt.capitalize! if config[:capitalize]

  if config[:capitalize_random]
    temp = attempt.chars
    temp[rand(temp.length)].upcase!
    attempt = temp.join
  end

  # An index histogram of matching leetables; ex: {"a"=>[9], "e"=>[0, 6], "i"=>[8]}
  if config[:l33t]
    leetables = {}
    LEET.keys.each do |l|
      matches = (0...attempt.length).find_all { |i| attempt[i, 1] == l }
      leetables[l] = matches unless matches.empty?
    end

    unless leetables.empty?
      leeted = leetables.to_a.sample(1).flatten.first # Get a random key from the histogram
      attempt.sub!(leeted, LEET[leeted][rand(LEET[leeted].length)]) # Change to gsub to replace all matches
    end
  end
  attempt
end
get_one() click to toggle source
# File lib/oro/parts.rb, line 62
def self.get_one
  list.sample
end
list_location() click to toggle source
# File lib/oro/parts.rb, line 6
def self.list_location
  @list_location
end
list_location=(location) click to toggle source
# File lib/oro/parts.rb, line 10
def self.list_location=(location)
  @list_location = location
end
listify() click to toggle source

instance_exec (vs. instance_eval) to pass params, define_singleton_method to add the class method

# File lib/oro/parts.rb, line 15
def self.listify
  list = YAML.load_file(@list_location)
  instance_exec(list) { |l| define_singleton_method('list') { @list ||= l } }
  self.respond_to?(:list) ? true : false
end
longest() click to toggle source
# File lib/oro/parts.rb, line 33
def self.longest
  @longest ||= list.empty? ? 0 : list.max { |a, b| a.length <=> b.length }.length
end
middle() click to toggle source
# File lib/oro/parts.rb, line 37
def self.middle
  (shortest + longest) / 2
end
shortest() click to toggle source
# File lib/oro/parts.rb, line 29
def self.shortest
  @shortest ||= list.empty? ? 0 : list.min { |a, b| a.length <=> b.length }.length
end
single_character_list?() click to toggle source
# File lib/oro/parts.rb, line 21
def self.single_character_list?
  (shortest == 1 && longest == 1) ? true : false
end
to_s() click to toggle source
# File lib/oro/parts.rb, line 110
def self.to_s
  "List #{name} > count:#{count}, shortest:#{shortest}, longest:#{longest}, middle:#{middle}, distinct:#{distinct?}, get one:'#{get_one}', contiguous:#{contiguous?}" + (absences.empty? ? '' : ", absences:#{absences}")
end