memorable_password 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.markdown +40 -0
- data/Rakefile +2 -0
- data/lib/memorable_password/blacklist.txt +262 -0
- data/lib/memorable_password/names.txt +44181 -0
- data/lib/memorable_password/sample.rb +7 -0
- data/lib/memorable_password/version.rb +3 -0
- data/lib/memorable_password.rb +102 -0
- data/memorable_password.gemspec +21 -0
- metadata +77 -0
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'memorable_password/sample'
|
2
|
+
|
3
|
+
module MemorablePassword
|
4
|
+
|
5
|
+
MAX_WORD_LENGTH = 7
|
6
|
+
DIGITS = (0..9).to_a.map{|d| d.to_s}
|
7
|
+
CHARACTERS = %w[! @ $ ? -]
|
8
|
+
|
9
|
+
DEFAULT_OPTIONS = {
|
10
|
+
:mixed_case => false,
|
11
|
+
:special_characters => false,
|
12
|
+
:length => nil
|
13
|
+
}
|
14
|
+
|
15
|
+
class << self; attr_accessor :dictionary, :blacklist end
|
16
|
+
@dictionary = nil
|
17
|
+
@blacklist = nil
|
18
|
+
|
19
|
+
def self.generate(opts={})
|
20
|
+
opts = DEFAULT_OPTIONS.merge(opts)
|
21
|
+
|
22
|
+
if opts[:length]
|
23
|
+
password = [(opts[:length] >= 9 ? long_word : word), (opts[:special_characters] ? character : digit)]
|
24
|
+
password << word(opts[:length] - password.compact.join.length)
|
25
|
+
|
26
|
+
if (count = opts[:length] - password.compact.join.length) > 0
|
27
|
+
count.times{ password << digit }
|
28
|
+
end
|
29
|
+
else
|
30
|
+
if opts[:special_characters]
|
31
|
+
password = [word, character, word, digit]
|
32
|
+
else
|
33
|
+
password = [word, digit, word]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
if opts[:mixed_case]
|
38
|
+
password.compact.reject{|x| x.length == 1}.sample.capitalize!
|
39
|
+
end
|
40
|
+
|
41
|
+
# 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.
|
42
|
+
if opts[:length] && password.compact.join.length > opts[:length]
|
43
|
+
password.compact.join.slice(0, opts[:length])
|
44
|
+
else
|
45
|
+
password.compact.join
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def self.character
|
52
|
+
CHARACTERS.sample
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.digit
|
56
|
+
DIGITS.sample
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.word(length=nil)
|
60
|
+
length = self.dictionary.keys.sample if !length || length > self.dictionary.keys.max
|
61
|
+
self.dictionary[length].sample if self.dictionary.has_key?(length)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.long_word
|
65
|
+
keys = self.dictionary.keys.sort
|
66
|
+
self.dictionary[keys.partition{|v| v >= keys[keys.size/2] }.first.sample].sample # Magic! It actually just randomly picks from the larger words..
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.initialize_dictionary
|
70
|
+
unless self.dictionary
|
71
|
+
self.dictionary = {}
|
72
|
+
self.blacklist = []
|
73
|
+
|
74
|
+
# Load blacklist from text file
|
75
|
+
File.foreach(File.join(File.dirname(__FILE__), 'memorable_password', 'blacklist.txt'))do |word|
|
76
|
+
word = word.strip.downcase
|
77
|
+
self.blacklist << word if word =~ /^[a-z]+$/
|
78
|
+
end
|
79
|
+
|
80
|
+
# Load system dictionary words
|
81
|
+
File.foreach("/usr/share/dict/words"){|word| add_word word}
|
82
|
+
|
83
|
+
# Load list of proper names
|
84
|
+
File.foreach(File.join(File.dirname(__FILE__), 'memorable_password', 'names.txt')){|word| add_word word}
|
85
|
+
end
|
86
|
+
|
87
|
+
self.dictionary
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.add_word(word)
|
91
|
+
word = word.strip.downcase
|
92
|
+
length = word.length
|
93
|
+
|
94
|
+
if length <= MAX_WORD_LENGTH && length > 1 && word =~ /^[a-z]+$/ && !self.blacklist.include?(word)
|
95
|
+
self.dictionary[length] = [] unless self.dictionary[length]
|
96
|
+
self.dictionary[length] << word
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
initialize_dictionary
|
101
|
+
|
102
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "memorable_password/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "memorable_password"
|
7
|
+
s.version = MemorablePassword::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Kevin McPhillips"]
|
10
|
+
s.email = ["github@kevinmcphillips.ca"]
|
11
|
+
s.homepage = "http://github.com/kimos/memorable_password"
|
12
|
+
s.summary = %q{Generate human readable and easy to remember passwords}
|
13
|
+
s.description = %q{This simple gem generates a random password that is easy to read and remember. It uses dictionary words as well as a list of proper names mixed in with numbers and special characters.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "memorable_password"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: memorable_password
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Kevin McPhillips
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-05-16 00:00:00 -05:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: This simple gem generates a random password that is easy to read and remember. It uses dictionary words as well as a list of proper names mixed in with numbers and special characters.
|
23
|
+
email:
|
24
|
+
- github@kevinmcphillips.ca
|
25
|
+
executables: []
|
26
|
+
|
27
|
+
extensions: []
|
28
|
+
|
29
|
+
extra_rdoc_files: []
|
30
|
+
|
31
|
+
files:
|
32
|
+
- .gitignore
|
33
|
+
- Gemfile
|
34
|
+
- README.markdown
|
35
|
+
- Rakefile
|
36
|
+
- lib/memorable_password.rb
|
37
|
+
- lib/memorable_password/blacklist.txt
|
38
|
+
- lib/memorable_password/names.txt
|
39
|
+
- lib/memorable_password/sample.rb
|
40
|
+
- lib/memorable_password/version.rb
|
41
|
+
- memorable_password.gemspec
|
42
|
+
has_rdoc: true
|
43
|
+
homepage: http://github.com/kimos/memorable_password
|
44
|
+
licenses: []
|
45
|
+
|
46
|
+
post_install_message:
|
47
|
+
rdoc_options: []
|
48
|
+
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
hash: 3
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project: memorable_password
|
72
|
+
rubygems_version: 1.3.7
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: Generate human readable and easy to remember passwords
|
76
|
+
test_files: []
|
77
|
+
|