is_passgen 1.1.2

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: af7b9b3a555ef8ef130dfa2bb70d84371b98eebd5de120794b38fbfbc2c9230c
4
+ data.tar.gz: c25e3ba05320d4f72d04355b34e091f4f2f2a61df95eff242a301c76a9902fb2
5
+ SHA512:
6
+ metadata.gz: f29e3d96b1207b65708c7656c69d74a0e9ef4d2efc478087f7109f8cbf44b9f40cce1095b4535f8d68fff401f7e3dc38b34ff66342014b4762f55b6dc655eeb6
7
+ data.tar.gz: fc039fbfa6fcafdb661ba1a2d24bde51eee0adaa94897ffeaf5c3c07191bff61574c6e819a0724c468d17ebb101113283071c5d636d09ee8d5e9e01627714c9c
@@ -0,0 +1,17 @@
1
+ v1.1.2 Added contributors
2
+
3
+ v1.1.1 Removed malicious dependency
4
+
5
+ v1.0.1 Corrected syntax error with ruby1.9.2
6
+
7
+ v1.0.0. Added password strength analyzer
8
+
9
+ v0.9.1. Had not added new files in 0.9.0 version
10
+
11
+ v0.9.0. Added pronounceable passwords
12
+
13
+ v0.1.3. Updated help
14
+
15
+ v0.1.2. Moved to rubygems.org
16
+
17
+ v0.1.1. First public release
@@ -0,0 +1,11 @@
1
+ CHANGELOG
2
+ Manifest
3
+ README.rdoc
4
+ Rakefile
5
+ rails/init.rb
6
+ lib/passgen.rb
7
+ lib/passgen/probabilities.rb
8
+ lib/passgen/strength_analyzer.rb
9
+ passgen.gemspec
10
+ spec/passgen/strength_analyzer_spec.rb
11
+ spec/passgen_spec.rb
@@ -0,0 +1,158 @@
1
+ = Passgen
2
+
3
+ Ruby gem for generating passwords quickly and easily. Although it is
4
+ suitable for use within Rails it has no Rails dependencies and can be used in
5
+ non-Rails applications as well.
6
+
7
+ It can generate passwords including lower case, upper case, digits and symbols and also
8
+ pronounceable passwords.
9
+
10
+ Since 1.0.0 you can also analyze the quality of a password, both as a numeric score
11
+ between 0 and 100 and as a complexity ranking.
12
+
13
+ The algorithm used exists in a number of variations for different languages, if if anyone
14
+ knows its origin and would like to include credit to the original author, please get in
15
+ touch via GitHub.
16
+
17
+ == Install
18
+
19
+ gem install passgen
20
+
21
+ == Usage
22
+
23
+ The usage could not be easier. Just require and call the generate method:
24
+
25
+ >> require 'rubygems'
26
+ >> require 'passgen'
27
+ >> Passgen.generate
28
+ => "zLWCeS3xC9"
29
+
30
+ You check the strength of a password by calling analyze:
31
+
32
+ >> info = Passgen.analyze("zLWCeS3xC9")
33
+ => #<Passgen::StrengthAnalyzer:0xb728654c @complexity="Strong", @score=78, @errors=[], @password="zLWCeS3xC9">
34
+ >> info.score
35
+ => 78
36
+ >> info.complexity
37
+ => "Strong"
38
+
39
+ == Examples
40
+
41
+ >> Passgen.generate
42
+ => "zLWCeS3xC9"
43
+
44
+ >> Passgen.generate(:length => 20)
45
+ => "6lCcHvkuEW6OuzAtkoAs"
46
+
47
+ >> Passgen.generate(:symbols => true)
48
+ => "gr)$6bIym1"
49
+
50
+ >> Passgen.generate(:lowercase => :only)
51
+ => "ysbwuxbcea"
52
+
53
+ >> Passgen.generate(:number => 3)
54
+ => ["REdOigTkdI", "PQu8DsV9WZ", "qptKLbw8YQ"]
55
+
56
+ >> Passgen.generate(:seed => 5)
57
+ => "JoV9M2qjiK"
58
+ >> Passgen.generate(:seed => 5) # Will generate same password again
59
+ => "JoV9M2qjiK"
60
+
61
+ >> Passgen.generate(:pronounceable => true) # Pronounceable, mixed case password
62
+ => "ActeodEuRT"
63
+ >> Passgen.generate(:pronounceable => true, :lowercase => :only) # Pronounceable lower case
64
+ => "terysolang"
65
+ >> Passgen.generate(:pronounceable => true, :uppercase => :only) # Pronounceable upper case
66
+ => "ACTOPECHEI"
67
+ >> Passgen.generate(:pronounceable => true, :digits_before => 3) # Pad with digits in front
68
+ => "886uRApLIN"
69
+ >> Passgen.generate(:pronounceable => true, :digits_before => 3) # Pad with digits at the end
70
+ => "uRAPLIN886"
71
+
72
+ == Options:
73
+
74
+ === :lowercase => true/false/:only
75
+ * true - Use lowercase letters in the generated password.
76
+ * false - Do not use lowercase letters in the generated password.
77
+ * :only - Only use lowercase letters in the generated password.
78
+
79
+ === :uppercase => true/false/:only
80
+ * true - Use uppercase letters in the generated password.
81
+ * false - Do not use uppercase letters in the generated password.
82
+ * :only - Only use uppercase letters in the generated password.
83
+
84
+ === :digits => true/false/:only
85
+ * true - Use digits in the generated password.
86
+ * false - Do not use digits in the generated password.
87
+ * :only - Only use digits in the generated password.
88
+
89
+ === :symbols => true/false/:only/:list
90
+ * true - Use symbols in the generated password.
91
+ * false - Do not use symbols in the generated password.
92
+ * :only - Only use symbols in the generated password.
93
+ * :list - A string with the symbols to use. Not implemented yet.
94
+
95
+ === :number => integer
96
+ Number of passwords to generate. If >1 the result is an Array.
97
+
98
+ === :length => integer/range
99
+ The number of characters in the generated passwords. A range results in passwords
100
+ lengths within the given range.
101
+
102
+ === :seed => integer/:default
103
+ Set the srand seed to the given integer prior to generating the passwords.
104
+
105
+ === :pronounceable => true/false
106
+ * true - Generate pronounceable passwords
107
+ * false - No effect
108
+
109
+ === :digits_after => true/number (Only in combination with :pronounceable)
110
+ * Pads the pronounceable password with number digits at the end. Defaults to 2 if true is passed.
111
+
112
+ === :digits_before => true/number (Only in combination with :pronounceable)
113
+ * Pads the pronounceable password with number digits in front. Defaults to 2 if true is passed.
114
+
115
+ === Default values:
116
+
117
+ :lowercase => true
118
+
119
+ :uppercase => true
120
+
121
+ :digits => true
122
+
123
+ :symbols => false
124
+
125
+ :pronounceable => Not implemented yet.
126
+
127
+ :number => 1
128
+
129
+ :length => 10
130
+
131
+ :seed => nil
132
+
133
+ :pronounceable => false
134
+
135
+ :digits_after => 2 (Only in combination with pronounceable)
136
+
137
+ :digits_before => 2 (Only in combination with pronounceable)
138
+
139
+ == Copyright and license
140
+
141
+ Permission is hereby granted, free of charge, to any person obtaining
142
+ a copy of this software and associated documentation files (the
143
+ "Software"), to deal in the Software without restriction, including
144
+ without limitation the rights to use, copy, modify, merge, publish,
145
+ distribute, sublicense, and/or sell copies of the Software, and to
146
+ permit persons to whom the Software is furnished to do so, subject to
147
+ the following conditions:
148
+
149
+ The above copyright notice and this permission notice shall be
150
+ included in all copies or substantial portions of the Software.
151
+
152
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
153
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
154
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
155
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
156
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
157
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
158
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,15 @@
1
+ # Rakefile
2
+ require 'rubygems'
3
+ require 'rake'
4
+ require 'echoe'
5
+
6
+ Echoe.new('passgen', '1.0.1') do |p|
7
+ p.description = "A password generation gem for Ruby and Rails applications."
8
+ p.url = "http://github.com/cryptice/passgen"
9
+ p.author = "Erik Lindblad"
10
+ p.email = "erik@l2c.se"
11
+ p.ignore_pattern = ["tmp/*", "script/*", "nbproject/*"]
12
+ p.development_dependencies = []
13
+ end
14
+
15
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
@@ -0,0 +1,329 @@
1
+ #= Passgen
2
+ #
3
+ # Ruby gem for generating passwords quickly and easily. Although it is
4
+ # suitable for use within Rails it has no Rails dependencies and can be used in
5
+ # non-Rails applications as well.
6
+ #
7
+ #== Install
8
+ #
9
+ # gem install cryptice-passgen --source http://gems.github.com
10
+ #
11
+ #== Usage
12
+ #
13
+ # The usage could not be easier. Just require and call the generate method:
14
+ #
15
+ # >> require 'rubygems'
16
+ # >> require 'passgen'
17
+ # >> Passgen::generate
18
+ # => "zLWCeS3xC9"
19
+ #
20
+ # == Examples
21
+ #
22
+ # >> Passgen::generate
23
+ # => "zLWCeS3xC9"
24
+ #
25
+ # >> Passgen::generate(length: 20)
26
+ # => "6lCcHvkuEW6OuzAtkoAs"
27
+ #
28
+ # >> Passgen::generate(symbols: true)
29
+ # => "gr)$6bIym1"
30
+ #
31
+ # >> Passgen::generate(lowercase: :only)
32
+ # => "ysbwuxbcea"
33
+ #
34
+ # >> Passgen::generate(number: 3)
35
+ # => ["REdOigTkdI", "PQu8DsV9WZ", "qptKLbw8YQ"]
36
+ #
37
+ # >> Passgen::generate(seed: 5)
38
+ # => "JoV9M2qjiK"
39
+ # >> Passgen::generate(seed: 5) # Will generate same password again
40
+ # => "JoV9M2qjiK"
41
+ #
42
+ # >> Passgen::generate(seed: :default) # Will set random seed...
43
+ # => "SI8QDBdV98"
44
+ # >> Passgen::generate(seed: :default) # and hence give different password
45
+ # => "tHHU5HLBAn"
46
+ #
47
+ # == Options:
48
+ #
49
+ # === :lowercase => true/false/:only
50
+ # * true - Use lowercase letters in the generated password.
51
+ # * false - Do not use lowercase letters in the generated password.
52
+ # * :only - Only use lowercase letters in the generated password.
53
+ #
54
+ # === :uppercase => true/false/:only
55
+ # * true - Use uppercase letters in the generated password.
56
+ # * false - Do not use uppercase letters in the generated password.
57
+ # * :only - Only use uppercase letters in the generated password.
58
+ #
59
+ # === :digits => true/false/:only
60
+ # * true - Use digits in the generated password.
61
+ # * false - Do not use digits in the generated password.
62
+ # * :only - Only use digits in the generated password.
63
+ #
64
+ # === :symbols => true/false/:only/:list
65
+ # * true - Use symbols in the generated password.
66
+ # * false - Do not use symbols in the generated password.
67
+ # * :only - Only use symbols in the generated password.
68
+ # * :list - A string with the symbols to use. Not implemented yet.
69
+ #
70
+ # === :pronounceable => true/false
71
+ # Not implmented yet.
72
+ #
73
+ # === :number => integer
74
+ # Number of passwords to generate. If >1 the result is an Array.
75
+ #
76
+ # === :length => integer/range
77
+ # The number of characters in the generated passwords. A range results in passwords
78
+ # lengths within the given range.
79
+ #
80
+ # === :seed => integer/:default
81
+ # Set the srand seed to the given integer prior to generating the passwords.
82
+ #
83
+ # === Default values:
84
+ #
85
+ # lowercase: true
86
+ #
87
+ # uppercase: true
88
+ #
89
+ # digits: true
90
+ #
91
+ # symbols: false
92
+ #
93
+ # pronounceable: Not implemented yet.
94
+ #
95
+ # number: 1
96
+ #
97
+ # length: 10
98
+ #
99
+ # seed: nil
100
+ #
101
+ # == Copyright and license
102
+ #
103
+ # Copyright (c) 2009 Erik Lindblad
104
+ #
105
+ # Permission is hereby granted, free of charge, to any person obtaining
106
+ # a copy of this software and associated documentation files (the
107
+ # "Software"), to deal in the Software without restriction, including
108
+ # without limitation the rights to use, copy, modify, merge, publish,
109
+ # distribute, sublicense, and/or sell copies of the Software, and to
110
+ # permit persons to whom the Software is furnished to do so, subject to
111
+ # the following conditions:
112
+ #
113
+ # The above copyright notice and this permission notice shall be
114
+ # included in all copies or substantial portions of the Software.
115
+ #
116
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
117
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
118
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
119
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
120
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
121
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
122
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
123
+
124
+ require 'digest'
125
+ require 'passgen/probabilities'
126
+ require 'passgen/strength_analyzer'
127
+
128
+ module Passgen
129
+
130
+ VERSION = "1.0.0"
131
+
132
+ DEFAULT_PARAMS = {
133
+ number: 1,
134
+ length: 10,
135
+ lowercase: true,
136
+ uppercase: true,
137
+ digits: true,
138
+ symbols: false,
139
+ pronounceable: false
140
+ }
141
+
142
+ def self.default_seed
143
+ Digest::MD5.hexdigest("#{rand}#{Time.now}#{Process.object_id}").to_i(16)
144
+ end
145
+
146
+ def self.generate(params = {})
147
+ set_options(params)
148
+ tokens = valid_tokens
149
+ set_seed
150
+
151
+ if n == 1
152
+ generate_one(tokens)
153
+ else
154
+ Array.new(n) { |i| generate_one(tokens) }
155
+ end
156
+ end
157
+
158
+ def self.analyze(pw)
159
+ Passgen::StrengthAnalyzer.analyze(pw)
160
+ end
161
+
162
+ private
163
+
164
+ def self.alphabet(index)
165
+ if use_lowercase? && !use_uppercase?
166
+ LOWERCASE_TOKENS[index]
167
+ elsif use_uppercase? && !use_lowercase?
168
+ UPPERCASE_TOKENS[index]
169
+ else
170
+ tmp = LOWERCASE_TOKENS[index]
171
+ tmp.upcase! if rand > 0.5
172
+ tmp
173
+ end
174
+ end
175
+
176
+ def self.generate_one(tokens)
177
+ if @options[:pronounceable]
178
+ generate_pronounceable
179
+ else
180
+ Array.new(password_length) { tokens[rand(tokens.size)] }.join
181
+ end
182
+ end
183
+
184
+ def self.generate_pronounceable
185
+ password = ""
186
+
187
+ # Append digits in front
188
+ digits_prefix = if @options[:digits_before]
189
+ @options[:length] -= @options[:digits_before]
190
+ Array.new(@options[:digits_before]) { DIGIT_TOKENS[rand(DIGIT_TOKENS.size)] }.join
191
+ else
192
+ ""
193
+ end
194
+
195
+ # Append digits at the end
196
+ digits_suffix = if @options[:digits_after]
197
+ @options[:length] -= @options[:digits_after]
198
+ Array.new(@options[:digits_after]) { DIGIT_TOKENS[rand(DIGIT_TOKENS.size)] }.join
199
+ else
200
+ ""
201
+ end
202
+
203
+ # Find a random starting point.
204
+ found_start = false
205
+ ranno = rand * SIGMA # random number [0,1[ weighed by sum of frequencies
206
+ sum = 0;
207
+ N_LETTERS.times do |c1|
208
+ N_LETTERS.times do |c2|
209
+ N_LETTERS.times do |c3|
210
+ sum += P[c1][c2][c3]
211
+ if sum > ranno
212
+ password << alphabet(c1)
213
+ password << alphabet(c2)
214
+ password << alphabet(c3)
215
+ found_start = true
216
+ break
217
+ end
218
+ end
219
+ break if found_start
220
+ end
221
+ break if found_start
222
+ end
223
+
224
+ # Do a random walk.
225
+ (3...@options[:length]).each do |nchar|
226
+ c1 = LETTER_INDEXES[password[nchar - 2..nchar - 2]]
227
+ c2 = LETTER_INDEXES[password[nchar - 1..nchar - 1]]
228
+ sum = 0
229
+ N_LETTERS.times { |c3| sum += P[c1][c2][c3] }
230
+ break if sum == 0
231
+ ranno = rand * sum
232
+ sum = 0
233
+ N_LETTERS.times do |c3|
234
+ sum += P[c1][c2][c3]
235
+ if sum > ranno
236
+ password << alphabet(c3)
237
+ break
238
+ end
239
+ end
240
+ end
241
+ digits_prefix + password + digits_suffix
242
+ end
243
+
244
+ def self.password_length
245
+ if @options[:length].is_a?(Range)
246
+ tmp = @options[:length].to_a
247
+ tmp[rand(tmp.size)]
248
+ else
249
+ @options[:length].to_i
250
+ end
251
+ end
252
+
253
+ def self.n
254
+ @options[:number]
255
+ end
256
+
257
+ def self.set_options(params)
258
+ if params[:lowercase] == :only
259
+ params[:uppercase] = false
260
+ params[:digits] = false
261
+ end
262
+
263
+ if params[:uppercase] == :only
264
+ params[:lowercase] = false
265
+ params[:digits] = false
266
+ end
267
+
268
+ if params[:digits] == :only
269
+ params[:lowercase] = false
270
+ params[:uppercase] = false
271
+ end
272
+
273
+ if params[:symbols] == :only
274
+ params[:lowercase] = false
275
+ params[:uppercase] = false
276
+ params[:digits] = false
277
+ params[:symbols] = true
278
+ end
279
+
280
+ if params[:digits_before] == true
281
+ params[:digits_before] = 2
282
+ end
283
+
284
+ if params[:digits_after] == true
285
+ params[:digits_after] = 2
286
+ end
287
+
288
+ @options = DEFAULT_PARAMS.merge(params)
289
+ end
290
+
291
+ def self.set_seed
292
+ if @options[:seed]
293
+ if @options[:seed] == :default
294
+ srand(default_seed)
295
+ else
296
+ srand(@options[:seed])
297
+ end
298
+ end
299
+ end
300
+
301
+ def self.symbol_tokens
302
+ %w{! @ # $ % & / ( ) + ? *}
303
+ end
304
+
305
+ def self.use_lowercase?
306
+ @options[:lowercase]
307
+ end
308
+
309
+ def self.use_uppercase?
310
+ @options[:uppercase]
311
+ end
312
+
313
+ def self.use_digits?
314
+ @options[:digits]
315
+ end
316
+
317
+ def self.use_symbols?
318
+ @options[:symbols]
319
+ end
320
+
321
+ def self.valid_tokens
322
+ tmp = []
323
+ tmp += LOWERCASE_TOKENS if use_lowercase?
324
+ tmp += UPPERCASE_TOKENS if use_uppercase?
325
+ tmp += DIGIT_TOKENS if use_digits?
326
+ tmp += symbol_tokens if use_symbols?
327
+ tmp
328
+ end
329
+ end