rassphrase 0.0.1 → 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/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
|