rassphrase 0.0.1 → 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog +7 -0
- data/README.md +73 -0
- data/bin/rassphrase +2 -2
- data/features/step_definitions/diceware_steps.rb +1 -1
- data/features/step_definitions/generate_passphrase_steps.rb +1 -1
- data/lib/rassphrase/dice.rb +6 -0
- data/lib/rassphrase/rassphrase.rb +51 -8
- data/lib/rassphrase/version.rb +1 -1
- data/lib/rassphrase/wordlist_parser.rb +13 -1
- data/rassphrase.gemspec +2 -2
- data/spec/rassphrase/rassphrase_spec.rb +74 -17
- metadata +9 -9
data/Changelog
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
0.1 (October 31, 2011)
|
2
|
+
Defaults :capitalize to true
|
3
|
+
Add option hash argument to Rassphrase#generate
|
4
|
+
Add boolean argument to Rassphrase#passphrase, that indicates capitalization
|
5
|
+
Rename Rassphrase#generate_code to Rassphrase#random_code
|
6
|
+
Add class method Rassphrase::generate
|
7
|
+
Overwrote Rassphrase#to_s
|
data/README.md
CHANGED
@@ -3,3 +3,76 @@ rassphrase
|
|
3
3
|
|
4
4
|
rassphrase is an implementation of the Diceware passphrase method for Ruby.
|
5
5
|
It's used to generate secure passphrase used for passwords.
|
6
|
+
|
7
|
+
What is Diceware?
|
8
|
+
=================
|
9
|
+
|
10
|
+
Diceware™ is a method for picking passphrases that uses dice to select words at
|
11
|
+
random from a special list called the Diceware Word List. Each word in the list
|
12
|
+
is preceded by a five digit number. All the digits are between one and six,
|
13
|
+
allowing you to use the outcomes of five dice rolls to select one unique word from the list.
|
14
|
+
|
15
|
+
More information about the Diceware method @ [http://diceware.com](http://diceware.com "Diceware Homepage")
|
16
|
+
|
17
|
+
|
18
|
+
Install
|
19
|
+
-------
|
20
|
+
|
21
|
+
### Gems
|
22
|
+
|
23
|
+
To install the latest "stable" version:
|
24
|
+
|
25
|
+
$ gem install rassphrase
|
26
|
+
|
27
|
+
To install the development version:
|
28
|
+
|
29
|
+
$ git clone git://github.com/guzart/rassphrase.git
|
30
|
+
$ cd rassphrase
|
31
|
+
$ git pull origin develop
|
32
|
+
$ git branch develop
|
33
|
+
$ rake install
|
34
|
+
|
35
|
+
### Bundler (inside your Gemfile)
|
36
|
+
|
37
|
+
To install the latest "stable" version:
|
38
|
+
|
39
|
+
gem 'rassphrase'
|
40
|
+
|
41
|
+
To install the development version:
|
42
|
+
|
43
|
+
gem 'rassphrase', :git => "git://github.com/guzart/rassphrase.git", :branch => "develop"
|
44
|
+
|
45
|
+
Usage
|
46
|
+
-----
|
47
|
+
|
48
|
+
### Ruby
|
49
|
+
|
50
|
+
Using an instance
|
51
|
+
|
52
|
+
require 'rassphrase'
|
53
|
+
rassphrase = Rassphrase::Rassphrase.new(:capitalize => true)
|
54
|
+
password = rassphrase.generate(10)
|
55
|
+
|
56
|
+
Using the class method
|
57
|
+
|
58
|
+
# Generates an array of 10 passphrases
|
59
|
+
require 'rassphrase'
|
60
|
+
passphrases = Rassphrase::Rassphrase.generate({:count => 10})
|
61
|
+
|
62
|
+
#### Options
|
63
|
+
|
64
|
+
+ **size** => Integer - The number of words that make a passphrase.
|
65
|
+
+ **capitalize** => Boolean - Indicates if the words in the passphrase should be capitalized.
|
66
|
+
+ **use_beale** => Boolean - Indicate if it should use the beale wordlist.
|
67
|
+
+ **wordlist_path** => String - A path to a wordlist to use
|
68
|
+
|
69
|
+
### Binary
|
70
|
+
|
71
|
+
rassphrase comes with a binary called....(drum roll) rassphrase.
|
72
|
+
|
73
|
+
rassphrase [options]
|
74
|
+
-h Shows the command options
|
75
|
+
-s SIZE The number of words in the passphrase
|
76
|
+
-c Capitalizes the words
|
77
|
+
-b Uses the Beale wordlist. More info @ diceware.com
|
78
|
+
-n NUMBER The number of different passphrase to generate, one per line
|
data/bin/rassphrase
CHANGED
@@ -18,8 +18,8 @@ optparse = OptionParser.new do |opts|
|
|
18
18
|
@options[:size] = s
|
19
19
|
end
|
20
20
|
|
21
|
-
opts.on("-c", "Capitalizes the words in the passphrase") do
|
22
|
-
@options[:capitalize] =
|
21
|
+
opts.on("-c", "--[no-]capitalize", "Capitalizes the words in the passphrase") do |c|
|
22
|
+
@options[:capitalize] = c
|
23
23
|
end
|
24
24
|
|
25
25
|
opts.on("-b", "Uses the Beale wordlist dictionary.") do |w|
|
@@ -7,7 +7,7 @@ When /^I generate a passphrase with (\d+) words$/ do |word_count|
|
|
7
7
|
end
|
8
8
|
|
9
9
|
Then /^I get a passphrase with concatenated words$/ do
|
10
|
-
@passphrase.should == @rassphrase.words.join
|
10
|
+
@passphrase.downcase.should == @rassphrase.words.join.downcase
|
11
11
|
end
|
12
12
|
|
13
13
|
Then /^all the words are different$/ do
|
data/lib/rassphrase/dice.rb
CHANGED
@@ -1,15 +1,21 @@
|
|
1
1
|
module Rassphrase
|
2
|
+
# Simulates a dice
|
2
3
|
class Dice
|
4
|
+
# Creates a new instance of a dice
|
3
5
|
def initialize
|
4
6
|
@random = Random.new
|
5
7
|
@roll_count = 0
|
6
8
|
end
|
7
9
|
|
10
|
+
# Returns a random number between 1 and the
|
11
|
+
# number of sides in the dice.
|
8
12
|
def roll
|
9
13
|
@roll_count += 1
|
10
14
|
@random.rand(1..6)
|
11
15
|
end
|
12
16
|
|
17
|
+
# Indicates the number of times the dice
|
18
|
+
# has been rolled.
|
13
19
|
def roll_count
|
14
20
|
@roll_count
|
15
21
|
end
|
@@ -1,64 +1,107 @@
|
|
1
1
|
module Rassphrase
|
2
2
|
class Rassphrase
|
3
|
+
|
4
|
+
def self.generate(options = {})
|
5
|
+
r = self.new(options)
|
6
|
+
count = options[:count] || 1
|
7
|
+
passphrases = []
|
8
|
+
count.times do
|
9
|
+
passphrases << r.generate
|
10
|
+
end
|
11
|
+
return passphrases.first if count == 1
|
12
|
+
passphrases
|
13
|
+
end
|
14
|
+
|
3
15
|
|
16
|
+
# Initializes an instance of Rassphrase with the specified options
|
17
|
+
#
|
18
|
+
# The rassphrase options are:
|
19
|
+
# * :dice => An instance of a class with a method roll, that returns a random number.
|
20
|
+
# * :size => The default number of words in a passphrase
|
21
|
+
# * :capitalize => Indicates if the words should be capitalize in the passphrase [defaults to true]
|
22
|
+
# * :wordlist_path => A path to a file containing a wordlist
|
23
|
+
# * :wordlist => The hash to use as a wordlist
|
4
24
|
def initialize(options = {})
|
5
25
|
@wordlist = []
|
6
26
|
@dice = options[:dice] || Dice.new
|
7
27
|
@size = options[:size] || 5
|
8
|
-
@capitalize = options[:capitalize] ||
|
28
|
+
@capitalize = options[:capitalize] || true
|
9
29
|
wordlist_path = options[:wordlist_path] || File.expand_path('../../diceware.wordlist', __FILE__)
|
10
30
|
self.wordlist = options[:wordlist] || WordlistParser::parse(wordlist_path)
|
11
31
|
self.generate
|
12
32
|
end
|
13
33
|
|
34
|
+
# The codes for the words used in the current passphrase.
|
14
35
|
def codes
|
15
36
|
@codes ||= []
|
16
37
|
end
|
17
38
|
|
18
|
-
|
19
|
-
|
39
|
+
# Generates a new passphrase.
|
40
|
+
# If a size is specified then it generates a passphrase with the given size.
|
41
|
+
def generate(options = nil)
|
42
|
+
capitalize = @capitalize
|
43
|
+
if options.kind_of?(Hash)
|
44
|
+
size = options[:size] || @size
|
45
|
+
capitalize = options[:capitalize] if options.has_key?(:capitalize)
|
46
|
+
else
|
47
|
+
size = options || @size
|
48
|
+
end
|
20
49
|
@words, @codes = [], []
|
21
50
|
size.times do
|
22
51
|
item = random_item
|
23
52
|
@codes << item[:code]
|
24
53
|
@words << item[:word]
|
25
54
|
end
|
26
|
-
self.passphrase
|
55
|
+
self.passphrase(capitalize)
|
27
56
|
end
|
28
57
|
|
29
|
-
|
58
|
+
# Generates random code
|
59
|
+
def random_code
|
30
60
|
code = ''
|
31
61
|
5.times { code << @dice.roll.to_s }
|
32
62
|
return code
|
33
63
|
end
|
34
64
|
|
65
|
+
# Returns the size of the passphrase
|
35
66
|
def length
|
36
67
|
self.words.length
|
37
68
|
end
|
38
69
|
|
39
|
-
|
40
|
-
|
70
|
+
alias :size :length
|
71
|
+
|
72
|
+
# Returns the generated passphrase
|
73
|
+
def passphrase(capitalize = nil)
|
74
|
+
capitalize = @capitalize if capitalize == nil
|
75
|
+
return self.words.join unless capitalize
|
41
76
|
self.words.map { |w| w.capitalize }.join
|
42
77
|
end
|
43
78
|
|
79
|
+
# Returns a random item from the wordlist
|
44
80
|
def random_item
|
45
81
|
word = nil
|
46
82
|
until word do
|
47
|
-
code = self.
|
83
|
+
code = self.random_code
|
48
84
|
word = self.word(code)
|
49
85
|
end
|
50
86
|
{:code => code, :word => word}
|
51
87
|
end
|
52
88
|
|
89
|
+
def to_s
|
90
|
+
self.passphrase
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns the word for the specified code searching the wordlist.
|
53
94
|
def word(code)
|
54
95
|
@wordlist[code.to_s]
|
55
96
|
end
|
56
97
|
|
98
|
+
# Assigns a new wordlist
|
57
99
|
def wordlist=(wordlist)
|
58
100
|
wordlist = WordlistParser::parse(wordlist) if wordlist.is_a?(String) && File.file?(wordlist)
|
59
101
|
@wordlist = wordlist.inject({}){ |wl, (k,v)| wl[k.to_s] = v; wl}
|
60
102
|
end
|
61
103
|
|
104
|
+
# Returns the words used in the passphrase
|
62
105
|
def words
|
63
106
|
@words ||= []
|
64
107
|
end
|
data/lib/rassphrase/version.rb
CHANGED
@@ -1,16 +1,28 @@
|
|
1
1
|
module Rassphrase
|
2
|
+
# Parses a file into a Hash, where the key is the
|
3
|
+
# code, and the value is the word.
|
4
|
+
# The file should have an item per line, where the code and the word
|
5
|
+
# are separated by a space.
|
6
|
+
# Example:
|
7
|
+
# 12345 hello
|
8
|
+
# 12346 world
|
9
|
+
# 12351 foo
|
2
10
|
class WordlistParser
|
11
|
+
|
12
|
+
# Parses a line into a hash with :code, and :word.
|
3
13
|
def self.parse_line(line)
|
4
14
|
items = line.split(' ')
|
5
15
|
{:code => items[0], :word => items[1]}
|
6
16
|
end
|
7
17
|
|
18
|
+
# Parses a file with wordlist items.
|
19
|
+
# A path to the file must be given as the first argument.
|
8
20
|
def self.parse(file_path)
|
9
21
|
wordlist = {}
|
10
22
|
File.open(file_path, 'r') do |file|
|
11
23
|
while line = file.gets
|
12
24
|
parts = self.parse_line(line)
|
13
|
-
wordlist[parts[:code]] = parts[:word]
|
25
|
+
wordlist[parts[:code].to_s] = parts[:word]
|
14
26
|
end
|
15
27
|
end
|
16
28
|
return wordlist
|
data/rassphrase.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.authors = ["Arturo Guzman"]
|
9
9
|
s.email = ["arturo@agrdt.com"]
|
10
10
|
s.homepage = "https://github.com/guzart/rassphrase"
|
11
|
-
s.summary = "A Ruby implementation of Diceware passphrase"
|
12
|
-
s.description = "Uses the Diceware
|
11
|
+
s.summary = "A Ruby implementation of Diceware passphrase."
|
12
|
+
s.description = "Uses the Diceware method and method to generate secure passphrases."
|
13
13
|
|
14
14
|
s.rubyforge_project = "rassphrase"
|
15
15
|
|
@@ -6,6 +6,34 @@ module Rassphrase
|
|
6
6
|
let(:rassphrase) { Rassphrase.new }
|
7
7
|
let(:beale_path) { File.expand_path("../../../lib/beale.wordlist", __FILE__) }
|
8
8
|
|
9
|
+
describe "::generate" do
|
10
|
+
it "defaults to 5 words" do
|
11
|
+
pending 'not sure how to do this test'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "defaults to generate 1 passphrase" do
|
15
|
+
Rassphrase.generate.should be_an_instance_of(String)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "defaults to capitalize words" do
|
19
|
+
pending 'not sure how to do this test'
|
20
|
+
end
|
21
|
+
|
22
|
+
context "accepts a hash argument that" do
|
23
|
+
it "uses :size to specify the size of the passphrase" do
|
24
|
+
pending 'same as defaults to 5 words'
|
25
|
+
end
|
26
|
+
|
27
|
+
it "uses :capitalize to return passphrase with capitalize words" do
|
28
|
+
pending 'same as defuaults to capitalize'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "uses :count to indicate how many passphrases should be generated" do
|
32
|
+
Rassphrase.generate(:count => 5).should have(5).passphrases
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
9
37
|
describe "#initialize" do
|
10
38
|
it "deaults to use the diceware wordlist" do
|
11
39
|
rassphrase.word("12345").should == "apathy"
|
@@ -15,14 +43,18 @@ module Rassphrase
|
|
15
43
|
rassphrase.should have(5).words
|
16
44
|
end
|
17
45
|
|
18
|
-
it "
|
19
|
-
rassphrase.passphrase.should
|
46
|
+
it "capitalizes words by default" do
|
47
|
+
rassphrase.passphrase.should == rassphrase.words.map{|w| w.capitalize}.join
|
20
48
|
end
|
21
49
|
|
22
|
-
|
50
|
+
it "generates an initial passphrase" do
|
51
|
+
rassphrase.words.should_not be_empty
|
52
|
+
end
|
53
|
+
|
54
|
+
context "accepts a hash argument with" do
|
23
55
|
it ":dice to specify the dice" do
|
24
56
|
dice = Dice.new
|
25
|
-
Rassphrase.new(:dice => dice).
|
57
|
+
Rassphrase.new(:dice => dice).random_code
|
26
58
|
dice.roll_count.should > 0
|
27
59
|
end
|
28
60
|
|
@@ -70,19 +102,46 @@ module Rassphrase
|
|
70
102
|
rassphrase.generate(8)
|
71
103
|
rassphrase.should have(8).words
|
72
104
|
end
|
105
|
+
|
106
|
+
context "accepts a hash argument with" do
|
107
|
+
it ":size to specify the size of the passphrase" do
|
108
|
+
rassphrase.generate(:size => 10)
|
109
|
+
rassphrase.should have(10).words
|
110
|
+
end
|
111
|
+
|
112
|
+
it ":capitalize to specify if words should be capitalized" do
|
113
|
+
passphrase = rassphrase.generate(:capitalize => false)
|
114
|
+
passphrase.should == rassphrase.words.join
|
115
|
+
end
|
116
|
+
end
|
73
117
|
end
|
74
118
|
|
75
|
-
describe "#
|
119
|
+
describe "#length" do
|
120
|
+
it "returns the number of words in the passphrase" do
|
121
|
+
rassphrase.should have(5).words
|
122
|
+
rassphrase.generate(9)
|
123
|
+
rassphrase.should have(9).words
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "#passphrase" do
|
128
|
+
it "returns the generated passphrase" do
|
129
|
+
passphrase = rassphrase.generate
|
130
|
+
rassphrase.passphrase.should == passphrase
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "#random_code" do
|
76
135
|
it "returns five characters" do
|
77
|
-
rassphrase.
|
136
|
+
rassphrase.random_code.size.should be 5
|
78
137
|
end
|
79
138
|
|
80
139
|
it "returns only numeric characters" do
|
81
|
-
rassphrase.
|
140
|
+
rassphrase.random_code.should match /\d{5}/
|
82
141
|
end
|
83
142
|
|
84
143
|
it "returns numeric characters between 1 and 6" do
|
85
|
-
code = rassphrase.
|
144
|
+
code = rassphrase.random_code.split('')
|
86
145
|
code.each do |c|
|
87
146
|
c.to_i.should be <= 6
|
88
147
|
c.to_i.should be >= 1
|
@@ -90,14 +149,6 @@ module Rassphrase
|
|
90
149
|
end
|
91
150
|
end
|
92
151
|
|
93
|
-
describe "#length" do
|
94
|
-
it "returns the number of words in the passphrase" do
|
95
|
-
rassphrase.should have(5).words
|
96
|
-
rassphrase.generate(9)
|
97
|
-
rassphrase.should have(9).words
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
152
|
describe "#random_item" do
|
102
153
|
it "returns a random code and word pair from the word list" do
|
103
154
|
item = rassphrase.random_item
|
@@ -109,6 +160,12 @@ module Rassphrase
|
|
109
160
|
end
|
110
161
|
end
|
111
162
|
|
163
|
+
describe "#to_s" do
|
164
|
+
it "returns the passphrase" do
|
165
|
+
rassphrase.to_s.should == rassphrase.passphrase
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
112
169
|
describe "#word" do
|
113
170
|
before(:each) { rassphrase.wordlist = wordlist }
|
114
171
|
|
@@ -127,7 +184,7 @@ module Rassphrase
|
|
127
184
|
|
128
185
|
describe "#words" do
|
129
186
|
it "returns the words used in the passphrase" do
|
130
|
-
rassphrase.passphrase.should == rassphrase.words.join
|
187
|
+
rassphrase.passphrase.downcase.should == rassphrase.words.join.downcase
|
131
188
|
end
|
132
189
|
end
|
133
190
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rassphrase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.1'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-11-01 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &2155894420 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2155894420
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: cucumber
|
27
|
-
requirement: &
|
27
|
+
requirement: &2155893400 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,9 +32,8 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
36
|
-
description: Uses the Diceware
|
37
|
-
passphrases.
|
35
|
+
version_requirements: *2155893400
|
36
|
+
description: Uses the Diceware method and method to generate secure passphrases.
|
38
37
|
email:
|
39
38
|
- arturo@agrdt.com
|
40
39
|
executables:
|
@@ -43,6 +42,7 @@ extensions: []
|
|
43
42
|
extra_rdoc_files: []
|
44
43
|
files:
|
45
44
|
- .gitignore
|
45
|
+
- Changelog
|
46
46
|
- Gemfile
|
47
47
|
- README.md
|
48
48
|
- Rakefile
|
@@ -89,7 +89,7 @@ rubyforge_project: rassphrase
|
|
89
89
|
rubygems_version: 1.8.11
|
90
90
|
signing_key:
|
91
91
|
specification_version: 3
|
92
|
-
summary: A Ruby implementation of Diceware passphrase
|
92
|
+
summary: A Ruby implementation of Diceware passphrase.
|
93
93
|
test_files:
|
94
94
|
- features/diceware.feature
|
95
95
|
- features/generate_passphrase.feature
|