jameswilding-secret 2.1.0
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/bin/secret +33 -0
- data/lib/secret/cli.rb +39 -0
- data/lib/secret/memorable.rb +54 -0
- data/lib/secret/password.rb +41 -0
- data/lib/secret.rb +7 -0
- metadata +57 -0
data/bin/secret
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'optparse'
|
3
|
+
require 'rubygems'
|
4
|
+
$:.unshift File.dirname(__FILE__) + '/../lib'
|
5
|
+
require 'secret'
|
6
|
+
|
7
|
+
options = {}
|
8
|
+
|
9
|
+
begin
|
10
|
+
# Command line switches
|
11
|
+
OptionParser.new do |opts|
|
12
|
+
opts.banner = "Usage: secret [options]"
|
13
|
+
|
14
|
+
opts.on('-l', '--length N', Integer, 'Make a password of length N (default is 10)') do |n|
|
15
|
+
options[:length] = n
|
16
|
+
end
|
17
|
+
|
18
|
+
opts.on('--memorable', 'Create a more memorable (but less secure) password using real words. Ignores --length') do
|
19
|
+
options[:memorable] = true
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.on('-H', '--hexed', 'Output both plain text and hexdigest-encrypted versions of the password') do
|
23
|
+
options[:hex] = true
|
24
|
+
end
|
25
|
+
|
26
|
+
end.parse!
|
27
|
+
rescue OptionParser::InvalidOption, OptionParser::InvalidArgument
|
28
|
+
puts "Usage: secret [--length N | --memorable] [--hexed]"
|
29
|
+
puts
|
30
|
+
puts "Try secret --help for more information."
|
31
|
+
else
|
32
|
+
Secret::CLI.execute(options)
|
33
|
+
end
|
data/lib/secret/cli.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
module Secret
|
2
|
+
module CLI
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def execute(options)
|
6
|
+
@@options = options
|
7
|
+
|
8
|
+
if options[:hex]
|
9
|
+
execute_with_hexing
|
10
|
+
else
|
11
|
+
execute_without_hexing
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def execute_without_hexing
|
17
|
+
say normal_or_memorable_password
|
18
|
+
end
|
19
|
+
|
20
|
+
def execute_with_hexing
|
21
|
+
password = normal_or_memorable_password
|
22
|
+
say "plain: #{password}", "hexed: #{password.hexed}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def normal_or_memorable_password
|
26
|
+
if @@options[:memorable]
|
27
|
+
Secret::Memorable::Password.new
|
28
|
+
else
|
29
|
+
Secret::Password.new(@@options)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def say(*things)
|
34
|
+
STDOUT.puts things.join("\n")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
module Secret
|
4
|
+
module Memorable
|
5
|
+
class Password < String
|
6
|
+
|
7
|
+
SYMBOLS = %w(@ $ % & +)
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@dictionary = Dictionary.new
|
11
|
+
super(random_words_symbols_and_numbers)
|
12
|
+
end
|
13
|
+
|
14
|
+
def hexed
|
15
|
+
Digest::SHA1.hexdigest(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def random_words_symbols_and_numbers
|
20
|
+
(random_words.join random_symbols_and_numbers).downcase
|
21
|
+
end
|
22
|
+
|
23
|
+
def random_words
|
24
|
+
[@dictionary.random, @dictionary.random]
|
25
|
+
end
|
26
|
+
|
27
|
+
def random_symbols_and_numbers
|
28
|
+
SYMBOLS[rand(SYMBOLS.length)] + random_numbers
|
29
|
+
end
|
30
|
+
|
31
|
+
def random_numbers
|
32
|
+
rand(10).to_s + rand(10).to_s
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Inspired by http://stephencelis.com/2009/03/29/whats-the-password-haddock.html
|
37
|
+
class Dictionary
|
38
|
+
|
39
|
+
PATHS = %w(/usr/share/dict/words /usr/share/words)
|
40
|
+
|
41
|
+
def random
|
42
|
+
words = get_words
|
43
|
+
words[rand(words.length)].chomp
|
44
|
+
end
|
45
|
+
|
46
|
+
def get_words
|
47
|
+
File.readlines(PATHS.first).select { |word| word.length < 6 }
|
48
|
+
rescue Errno::ENOENT
|
49
|
+
File.readlines(PATHS.last).select { |word| word.length < 6 }
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
|
3
|
+
module Secret
|
4
|
+
class Password < String
|
5
|
+
|
6
|
+
LETTERS = ('a'..'z').to_a
|
7
|
+
NUMBERS = ('0'..'9').to_a
|
8
|
+
|
9
|
+
def initialize(options={})
|
10
|
+
@count = options[:length] || 10
|
11
|
+
super(random_characters)
|
12
|
+
rescue SystemStackError => e
|
13
|
+
raise e, 'try specifying a shorter password length'
|
14
|
+
end
|
15
|
+
|
16
|
+
def hexed
|
17
|
+
Digest::SHA1.hexdigest(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def random_characters(result=[])
|
22
|
+
@count.times do
|
23
|
+
result << random_character
|
24
|
+
end
|
25
|
+
unique_characters_in(result) == @count ? result.join : random_characters
|
26
|
+
end
|
27
|
+
|
28
|
+
def random_character
|
29
|
+
c = characters[rand(characters.length)]
|
30
|
+
rand(2).eql?(1) ? c : c.upcase
|
31
|
+
end
|
32
|
+
|
33
|
+
def characters
|
34
|
+
LETTERS + NUMBERS
|
35
|
+
end
|
36
|
+
|
37
|
+
def unique_characters_in(array)
|
38
|
+
array.map { |x| x.downcase rescue x }.uniq.length
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/secret.rb
ADDED
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jameswilding-secret
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- James Wilding
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-06-17 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: secret generates random, alphanumeric passwords of up to twenty characters, and kinda-random memorable passwords too.
|
17
|
+
email:
|
18
|
+
executables:
|
19
|
+
- secret
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- bin/secret
|
26
|
+
- lib/secret.rb
|
27
|
+
- lib/secret/cli.rb
|
28
|
+
- lib/secret/memorable.rb
|
29
|
+
- lib/secret/password.rb
|
30
|
+
has_rdoc: false
|
31
|
+
homepage:
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
|
35
|
+
require_paths:
|
36
|
+
- lib
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: "0"
|
42
|
+
version:
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: "0"
|
48
|
+
version:
|
49
|
+
requirements: []
|
50
|
+
|
51
|
+
rubyforge_project:
|
52
|
+
rubygems_version: 1.2.0
|
53
|
+
signing_key:
|
54
|
+
specification_version: 2
|
55
|
+
summary: random/memorable password generator with command-line utility
|
56
|
+
test_files: []
|
57
|
+
|