Class: MemorablePassword
- Inherits:
-
Object
- Object
- MemorablePassword
- Defined in:
- lib/memorable_password.rb,
lib/memorable_password/version.rb
Overview
This class is used for generating memorable passwords. It generates the password from a list of words, proper names, digits and characters.
If no options are passed in, the dictionary is built from ‘/usr/share/dict/words’.
Options are:
-
ban_list- an array of words that should added to the blacklist -
dictionary_paths- an array of paths to files that contain dictionary words -
blacklist_paths- an array of paths to files that contain blacklisted words
Option examples:
MemorablePassword.new(:ban_list => ['bad word'])
MemorablePassword.new(:dictionary_paths => ['path_to_dictionary/dict.txt'])
MemorablePassword.new(:blacklist_paths => ['path_to_blacklist/blacklist.txt'])
Generate password
Generate a random password by calling #generate. See #generate for configuration details.
MemorablePassword.new.generate
# => "fig7joeann"
Generate simple password
Generate a simple 9-character password by calling #generate_simple.
MemorablePassword.new.generate_simple
# => "sons3pied"
Constant Summary collapse
- MAX_WORD_LENGTH =
7- DIGITS =
%w[0 1 2 3 4 5 6 7 8 9].freeze
- NON_WORD_DIGITS =
(DIGITS - %w(2 4 8)).freeze
- CHARACTERS =
%w[! @ $ ? -].freeze
- DEFAULT_PATH =
The default paths to the various dictionary flat files
"#{File.dirname(__FILE__)}/memorable_password"- DEFAULT_DICTIONARY_PATHS =
['/usr/share/dict/words', "#{DEFAULT_PATH}/names.txt"]
- DEFAULT_BLACKLIST_PATHS =
["#{DEFAULT_PATH}/blacklist.txt"]
- DEFAULT_GENERATE_OPTIONS =
{ :mixed_case => false, :special_characters => false, :length => nil, :min_length => nil }
- VERSION =
"0.1.3"
Instance Attribute Summary collapse
-
#ban_list ⇒ Object
readonly
Returns the value of attribute ban_list.
-
#blacklist ⇒ Object
readonly
Returns the value of attribute blacklist.
-
#blacklist_paths ⇒ Object
readonly
Returns the value of attribute blacklist_paths.
-
#dictionary ⇒ Object
readonly
Returns the value of attribute dictionary.
-
#dictionary_paths ⇒ Object
readonly
Returns the value of attribute dictionary_paths.
Instance Method Summary collapse
-
#add_word(word) ⇒ Object
Adds the
wordto the dictionary unless it is invalid or blacklisted. -
#blacklist_word(word) ⇒ Object
Adds the
wordto the blacklist unless it is invalid. -
#generate(opts = {}) ⇒ Object
Generates memorable password.
-
#generate_simple ⇒ Object
Generates memorable password as a combination of two 4-letter dictionary words joined by a numeric character excluding 2, 4 and 8.
-
#initialize(options = {}) ⇒ MemorablePassword
constructor
A new instance of MemorablePassword.
- #inspect ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ MemorablePassword
52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/memorable_password.rb', line 52 def initialize(={}) # TODO implement these lists as Sets to get Hash lookup and uniqueness for free -- matt.dressel 20120328 # The dictionary is currently a hash of length to words: {1 => ['w','a'], 2 => ['at']} @ban_list = .fetch(:ban_list, []) # TODO support passing data in as an array -- matt.dressel 20120328 @dictionary_paths = .fetch(:dictionary_paths, DEFAULT_DICTIONARY_PATHS) @blacklist_paths = .fetch(:blacklist_paths, DEFAULT_BLACKLIST_PATHS) @dictionary = {} @blacklist = [] build_dictionary end |
Instance Attribute Details
#ban_list ⇒ Object (readonly)
Returns the value of attribute ban_list.
49 50 51 |
# File 'lib/memorable_password.rb', line 49 def ban_list @ban_list end |
#blacklist ⇒ Object (readonly)
Returns the value of attribute blacklist.
49 50 51 |
# File 'lib/memorable_password.rb', line 49 def blacklist @blacklist end |
#blacklist_paths ⇒ Object (readonly)
Returns the value of attribute blacklist_paths.
49 50 51 |
# File 'lib/memorable_password.rb', line 49 def blacklist_paths @blacklist_paths end |
#dictionary ⇒ Object (readonly)
Returns the value of attribute dictionary.
49 50 51 |
# File 'lib/memorable_password.rb', line 49 def dictionary @dictionary end |
#dictionary_paths ⇒ Object (readonly)
Returns the value of attribute dictionary_paths.
49 50 51 |
# File 'lib/memorable_password.rb', line 49 def dictionary_paths @dictionary_paths end |
Instance Method Details
#add_word(word) ⇒ Object
Adds the word to the dictionary unless it is invalid or blacklisted
136 137 138 139 140 141 142 143 144 145 |
# File 'lib/memorable_password.rb', line 136 def add_word(word) return unless validate_word(word) word = normalize_word(word) unless @blacklist.include?(word) length = word.length @dictionary[length] = [] unless @dictionary[length] @dictionary[length] << word end end |
#blacklist_word(word) ⇒ Object
Adds the word to the blacklist unless it is invalid
148 149 150 151 152 153 154 155 156 |
# File 'lib/memorable_password.rb', line 148 def blacklist_word(word) return unless validate_word(word) word = normalize_word(word) @blacklist << word # Remove the blacklisted word from the dictionary if it exists dictionary_array = @dictionary[word.length] dictionary_array.delete(word) if dictionary_array && dictionary_array.include?(word) end |
#generate(opts = {}) ⇒ Object
Generates memorable password.
opts-
hash with options
- :mixed_case
-
trueorfalse- use mixedCase (default:false) - :special_characters
-
trueorfalse- use special characters like ! @ $? - (default:false) - :length
-
Fixnum - generate passoword with specific length
- :min_length
-
Fixnum - generate passoword with length grather or equal of specified
Options :length and :min_length are incompatible.
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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/memorable_password.rb', line 80 def generate(opts={}) opts = DEFAULT_GENERATE_OPTIONS.merge(opts) raise "You cannot specify :length and :min_length at the same time" if opts[:length] && opts[:min_length] if opts[:length] password = [(opts[:length] >= 8 ? long_word : word), (opts[:special_characters] ? character : digit)] password << word(opts[:length] - password.compact.join.length) if (count = opts[:length] - password.compact.join.length) > 0 if count == 1 password << digit else password << word(count) end end elsif opts[:special_characters] password = [word, character, word, digit] else password = [word, non_word_digit, long_word] end if opts[:mixed_case] password.compact.reject{|x| x.length == 1}.sample.capitalize! end # If a minimum length is required and this password is too short compact_password_length = password.compact.join.length if opts[:min_length] && compact_password_length < opts[:min_length] if (count = opts[:min_length] - compact_password_length) == 1 password << digit else password << word(count) end end # If it is too long, just cut it down to size. This should not happen often unless the :length option is present and is very small. compact_password_string = password.compact.join if opts[:length] && compact_password_string.length > opts[:length] result = compact_password_string.slice(0, opts[:length]) # If there is no digit then it is probably a short password that by chance is just a dictionary word. Override that because that is bad. if result =~ /^[a-z]+$/ password = [(opts[:mixed_case] ? word(opts[:length] - 1).capitalize : word(opts[:length] - 1)), (opts[:special_characters] ? character : digit)] result = password.compact.join end result else compact_password_string end end |
#generate_simple ⇒ Object
Generates memorable password as a combination of two 4-letter dictionary words joined by a numeric character excluding 2, 4 and 8.
69 70 71 |
# File 'lib/memorable_password.rb', line 69 def generate_simple "#{word(4)}#{non_word_digit}#{word(4)}" end |
#inspect ⇒ Object
158 159 160 |
# File 'lib/memorable_password.rb', line 158 def inspect to_s end |