spass 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +27 -0
- data/README.md +80 -0
- data/bin/spass +52 -0
- data/lib/spass.rb +43 -0
- data/spass.gemspec +23 -0
- data/spec/data/ten_words +10 -0
- data/spec/spass_spec.rb +69 -0
- metadata +104 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
spass (0.0.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
diff-lcs (1.1.3)
|
10
|
+
rcov (0.9.11)
|
11
|
+
rspec (2.7.0)
|
12
|
+
rspec-core (~> 2.7.0)
|
13
|
+
rspec-expectations (~> 2.7.0)
|
14
|
+
rspec-mocks (~> 2.7.0)
|
15
|
+
rspec-core (2.7.1)
|
16
|
+
rspec-expectations (2.7.0)
|
17
|
+
diff-lcs (~> 1.1.2)
|
18
|
+
rspec-mocks (2.7.0)
|
19
|
+
|
20
|
+
PLATFORMS
|
21
|
+
ruby
|
22
|
+
|
23
|
+
DEPENDENCIES
|
24
|
+
bundler (~> 1.0)
|
25
|
+
rcov
|
26
|
+
rspec (>= 2.2.0)
|
27
|
+
spass!
|
data/README.md
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
spass
|
2
|
+
=====
|
3
|
+
|
4
|
+
spass is a simple passphrase generator that chooses random words from a
|
5
|
+
dictionary. It was inspired by [an XKCD strip](http://xkcd.com/936/)
|
6
|
+
which reminds us that hard-to-remember passwords are not necessarily hard for a
|
7
|
+
computer to guess.
|
8
|
+
|
9
|
+
|
10
|
+
Prerequisites
|
11
|
+
-------------
|
12
|
+
|
13
|
+
Currently, spass only words on Unix-like systems, which are expected to have a
|
14
|
+
`/usr/share/dict/words` file. Future versions may support other platforms.
|
15
|
+
|
16
|
+
|
17
|
+
Installation
|
18
|
+
------------
|
19
|
+
|
20
|
+
spass is distributed as a gem, so just do:
|
21
|
+
|
22
|
+
$ gem install spass
|
23
|
+
|
24
|
+
|
25
|
+
Usage
|
26
|
+
-----
|
27
|
+
|
28
|
+
Run `spass` from the command-line to see usage notes. The first argument is the
|
29
|
+
minimum passphrase length (in characters). Examples:
|
30
|
+
|
31
|
+
$ spass 12
|
32
|
+
hive frighten
|
33
|
+
|
34
|
+
$ spass 24
|
35
|
+
moppet castigator harvesters
|
36
|
+
|
37
|
+
$ spass 32
|
38
|
+
munificent icebound raymond clorets
|
39
|
+
|
40
|
+
Passphrases are guaranteed to be at least as long as the given number, but
|
41
|
+
may be longer. By default, the words are taken from `/usr/share/dict/words`;
|
42
|
+
if you want to use words from a different dictionary, pass a second argument:
|
43
|
+
|
44
|
+
$ spass 12 my_words.txt
|
45
|
+
|
46
|
+
|
47
|
+
Future plans
|
48
|
+
------------
|
49
|
+
|
50
|
+
- Optional inclusion of uppercase, numbers, symbols
|
51
|
+
- Avoid word repetition
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
MIT License
|
56
|
+
-----------
|
57
|
+
|
58
|
+
spass is licensed under the MIT License.
|
59
|
+
|
60
|
+
Copyright (c) 2011 Eric Pierce
|
61
|
+
|
62
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
63
|
+
a copy of this software and associated documentation files (the
|
64
|
+
"Software"), to deal in the Software without restriction, including
|
65
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
66
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
67
|
+
permit persons to whom the Software is furnished to do so, subject to
|
68
|
+
the following conditions:
|
69
|
+
|
70
|
+
The above copyright notice and this permission notice shall be
|
71
|
+
included in all copies or substantial portions of the Software.
|
72
|
+
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
74
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
75
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
76
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
77
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
78
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
79
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
80
|
+
|
data/bin/spass
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'spass' # Is this needed?
|
4
|
+
|
5
|
+
USAGE = <<EOF
|
6
|
+
spass: Generate a passphrase with lowercase words
|
7
|
+
|
8
|
+
Usage:
|
9
|
+
|
10
|
+
$ spass <length> [path_to_dict]
|
11
|
+
|
12
|
+
This script generates a plain-English passphrase of at least the given length
|
13
|
+
(in characters), using random words from the given dictionary file
|
14
|
+
(/usr/share/dict/words by default). Only lowercase letters a-z will be included
|
15
|
+
in the output, making passphrases relatively easy to type (though usually
|
16
|
+
nonsensical).
|
17
|
+
|
18
|
+
Examples:
|
19
|
+
|
20
|
+
$ spass 12
|
21
|
+
hive frighten
|
22
|
+
|
23
|
+
$ spass 24
|
24
|
+
moppet castigator harvesters
|
25
|
+
|
26
|
+
$ spass 32
|
27
|
+
munificent icebound raymond clorets
|
28
|
+
|
29
|
+
A 32-character passphrase has about 120 bits of entropy, which is overkill for
|
30
|
+
most purposes. A 24-character passphrase clocks in at about 90 bits of entropy,
|
31
|
+
suitable for most high-security applications like root passwords or financial
|
32
|
+
records. You might want to use a password checker to verify the strength of
|
33
|
+
your passphrase after generating one that you like:
|
34
|
+
|
35
|
+
http://rumkin.com/tools/password/passchk.php
|
36
|
+
|
37
|
+
Inspired by http://xkcd.com/936/
|
38
|
+
EOF
|
39
|
+
|
40
|
+
if ARGV.count == 0
|
41
|
+
puts USAGE
|
42
|
+
else
|
43
|
+
length = ARGV[0].to_i
|
44
|
+
if ARGV[1]
|
45
|
+
sp = SPass.new(ARGV[1])
|
46
|
+
else
|
47
|
+
sp = SPass.new
|
48
|
+
end
|
49
|
+
puts sp.generate(length)
|
50
|
+
end
|
51
|
+
|
52
|
+
|
data/lib/spass.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
class SPass
|
3
|
+
attr_reader :dict_path, :dict_lines
|
4
|
+
|
5
|
+
def initialize(dict_path='/usr/share/dict/words')
|
6
|
+
@dict_path = File.expand_path(dict_path)
|
7
|
+
if !File.file?(@dict_path)
|
8
|
+
raise RuntimeError, "Cannot find dict file: #{@dict_path}"
|
9
|
+
end
|
10
|
+
@dict_lines = `wc -l #{@dict_path}`.split.first.to_i
|
11
|
+
end
|
12
|
+
|
13
|
+
# Return a random line number from 1..N where N is the last line
|
14
|
+
# in the dict file
|
15
|
+
def random_line
|
16
|
+
rand(@dict_lines) + 1
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return a random word from the dictionary, lowercased
|
20
|
+
def random_word
|
21
|
+
cmd = "sed -n '#{random_line} {p;q;}' '#{@dict_path}'"
|
22
|
+
`#{cmd}`.chomp.downcase
|
23
|
+
end
|
24
|
+
|
25
|
+
# Return a random word that consists of only lowercase letters
|
26
|
+
def random_ascii_word
|
27
|
+
word = random_word
|
28
|
+
while word =~ /[^a-z]/
|
29
|
+
word = random_word
|
30
|
+
end
|
31
|
+
return word
|
32
|
+
end
|
33
|
+
|
34
|
+
# Generate a passphrase of at least the given length in characters
|
35
|
+
def generate(length)
|
36
|
+
phrase = ''
|
37
|
+
while phrase.length < length + 1 # to account for trailing space
|
38
|
+
phrase += random_ascii_word + ' '
|
39
|
+
end
|
40
|
+
return phrase.chomp
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
data/spass.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "spass"
|
3
|
+
s.version = "0.0.1"
|
4
|
+
s.summary = "Generate passphrases"
|
5
|
+
s.description = <<-EOS
|
6
|
+
spass generates passphrases using random words
|
7
|
+
EOS
|
8
|
+
s.authors = ["Eric Pierce"]
|
9
|
+
s.email = "wapcaplet88@gmail.com"
|
10
|
+
s.homepage = "http://github.com/wapcaplet/spass"
|
11
|
+
s.platform = Gem::Platform::RUBY
|
12
|
+
|
13
|
+
s.add_development_dependency 'rspec', '>= 2.2.0'
|
14
|
+
s.add_development_dependency 'rcov'
|
15
|
+
#s.add_development_dependency 'yard'
|
16
|
+
#s.add_development_dependency 'bluecloth'
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.require_path = 'lib'
|
20
|
+
|
21
|
+
s.executables = ['spass']
|
22
|
+
end
|
23
|
+
|
data/spec/data/ten_words
ADDED
data/spec/spass_spec.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spass'
|
2
|
+
|
3
|
+
TEST_DICT = File.expand_path('../data/ten_words', __FILE__)
|
4
|
+
|
5
|
+
describe SPass do
|
6
|
+
before(:each) do
|
7
|
+
@sp = SPass.new(TEST_DICT)
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
describe "#initialize" do
|
12
|
+
it "correctly sets dict_path" do
|
13
|
+
path = TEST_DICT
|
14
|
+
@sp = SPass.new(path)
|
15
|
+
@sp.dict_path.should == path
|
16
|
+
end
|
17
|
+
|
18
|
+
it "raises an exception for invalid path" do
|
19
|
+
path = File.expand_path('non/existent/path')
|
20
|
+
lambda do
|
21
|
+
@sp = SPass.new(path)
|
22
|
+
end.should raise_error(RuntimeError, /Cannot find dict file/)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
describe "#random_line" do
|
28
|
+
it "is >= 1" do
|
29
|
+
100.times do
|
30
|
+
@sp.random_line.should be >= 1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "is <= number of lines" do
|
35
|
+
100.times do
|
36
|
+
@sp.random_line.should be <= @sp.dict_lines
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
describe "#random_word" do
|
43
|
+
it "only returns words from the dict" do
|
44
|
+
100.times do
|
45
|
+
@sp.random_word.should =~ /one|two|three|four|five|six|seven|eight|nine|ten/
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
describe "#random_ascii_word" do
|
52
|
+
it "only includes lowercase letters" do
|
53
|
+
10.times do
|
54
|
+
@sp.random_ascii_word.should =~ /^[a-z]+$/
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#generate" do
|
60
|
+
it "is at least the given length" do
|
61
|
+
[10, 15, 20, 25, 30, 35, 40].each do |len|
|
62
|
+
10.times do
|
63
|
+
@sp.generate(len).length.should be >= len
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: spass
|
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
|
+
- Eric Pierce
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-10-30 00:00:00 -06:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 7
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 2
|
33
|
+
- 0
|
34
|
+
version: 2.2.0
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rcov
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 3
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
version: "0"
|
49
|
+
type: :development
|
50
|
+
version_requirements: *id002
|
51
|
+
description: " spass generates passphrases using random words\n"
|
52
|
+
email: wapcaplet88@gmail.com
|
53
|
+
executables:
|
54
|
+
- spass
|
55
|
+
extensions: []
|
56
|
+
|
57
|
+
extra_rdoc_files: []
|
58
|
+
|
59
|
+
files:
|
60
|
+
- .gitignore
|
61
|
+
- Gemfile
|
62
|
+
- Gemfile.lock
|
63
|
+
- README.md
|
64
|
+
- bin/spass
|
65
|
+
- lib/spass.rb
|
66
|
+
- spass.gemspec
|
67
|
+
- spec/data/ten_words
|
68
|
+
- spec/spass_spec.rb
|
69
|
+
has_rdoc: true
|
70
|
+
homepage: http://github.com/wapcaplet/spass
|
71
|
+
licenses: []
|
72
|
+
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options: []
|
75
|
+
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
hash: 3
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
version: "0"
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
hash: 3
|
93
|
+
segments:
|
94
|
+
- 0
|
95
|
+
version: "0"
|
96
|
+
requirements: []
|
97
|
+
|
98
|
+
rubyforge_project:
|
99
|
+
rubygems_version: 1.3.7
|
100
|
+
signing_key:
|
101
|
+
specification_version: 3
|
102
|
+
summary: Generate passphrases
|
103
|
+
test_files: []
|
104
|
+
|