Class: Part

Inherits:
Object
  • Object
show all
Defined in:
lib/oro/parts.rb

Overview

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

Constant Summary collapse

LEET =
{ 'a' => ['@'], 'b' => ['|3'], 'd' => ['|)'], 'e' => ['3'], 'f' => ['ph'], 'i' => ['|'], 'k' => ['|<'],
'l' => ['|_'], 'o' => ['0'], 'p' => ['|*'], 's' => ['$', '5'], 'w' => ["'//"] }

Class Method Summary collapse

Class Method Details

.absencesObject



53
54
55
56
57
58
59
60
# 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?Boolean

Returns:

  • (Boolean)


49
50
51
# File 'lib/oro/parts.rb', line 49

def self.contiguous?
  absences.empty?
end

.countObject



25
26
27
# File 'lib/oro/parts.rb', line 25

def self.count
  list.size
end

.descendantsObject



45
46
47
# File 'lib/oro/parts.rb', line 45

def self.descendants
  ObjectSpace.each_object(Class).select { |klass| klass < self }
end

.distinct?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/oro/parts.rb', line 41

def self.distinct?
  list.size == list.uniq.size ? true : false
end

.get(size, config = {}) ⇒ Object



66
67
68
# 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) ⇒ Object



70
71
72
73
74
75
76
# 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 = {}) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# 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_oneObject



62
63
64
# File 'lib/oro/parts.rb', line 62

def self.get_one
  list.sample
end

.list_locationObject



6
7
8
# File 'lib/oro/parts.rb', line 6

def self.list_location
  @list_location
end

.list_location=(location) ⇒ Object



10
11
12
# File 'lib/oro/parts.rb', line 10

def self.list_location=(location)
  @list_location = location
end

.listifyObject

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



15
16
17
18
19
# 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

.longestObject



33
34
35
# File 'lib/oro/parts.rb', line 33

def self.longest
  @longest ||= list.empty? ? 0 : list.max { |a, b| a.length <=> b.length }.length
end

.middleObject



37
38
39
# File 'lib/oro/parts.rb', line 37

def self.middle
  (shortest + longest) / 2
end

.shortestObject



29
30
31
# 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?Boolean

Returns:

  • (Boolean)


21
22
23
# File 'lib/oro/parts.rb', line 21

def self.single_character_list?
  (shortest == 1 && longest == 1) ? true : false
end

.to_sObject



110
111
112
# 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