zxcvbn-ruby 0.0.3 → 1.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.
- checksums.yaml +7 -0
- data/.travis.yml +12 -0
- data/CHANGELOG.md +42 -0
- data/CODE_OF_CONDUCT.md +130 -0
- data/Gemfile +8 -1
- data/Guardfile +26 -0
- data/{LICENSE → LICENSE.txt} +0 -0
- data/README.md +165 -9
- data/Rakefile +5 -1
- data/lib/zxcvbn.rb +10 -36
- data/lib/zxcvbn/crack_time.rb +44 -42
- data/lib/zxcvbn/data.rb +29 -0
- data/lib/zxcvbn/dictionary_ranker.rb +0 -2
- data/lib/zxcvbn/entropy.rb +3 -1
- data/lib/zxcvbn/feedback.rb +10 -0
- data/lib/zxcvbn/feedback_giver.rb +133 -0
- data/lib/zxcvbn/matchers/date.rb +2 -0
- data/lib/zxcvbn/matchers/dictionary.rb +2 -0
- data/lib/zxcvbn/matchers/digits.rb +2 -0
- data/lib/zxcvbn/matchers/l33t.rb +2 -2
- data/lib/zxcvbn/matchers/regex_helpers.rb +2 -0
- data/lib/zxcvbn/matchers/repeat.rb +2 -0
- data/lib/zxcvbn/matchers/sequences.rb +2 -0
- data/lib/zxcvbn/matchers/spatial.rb +2 -0
- data/lib/zxcvbn/matchers/year.rb +2 -0
- data/lib/zxcvbn/math.rb +2 -2
- data/lib/zxcvbn/omnimatch.rb +14 -3
- data/lib/zxcvbn/password_strength.rb +7 -3
- data/lib/zxcvbn/score.rb +1 -1
- data/lib/zxcvbn/scorer.rb +11 -0
- data/lib/zxcvbn/tester.rb +43 -0
- data/lib/zxcvbn/version.rb +1 -1
- data/spec/dictionary_ranker_spec.rb +2 -2
- data/spec/feedback_giver_spec.rb +212 -0
- data/spec/matchers/date_spec.rb +8 -8
- data/spec/matchers/dictionary_spec.rb +25 -14
- data/spec/matchers/digits_spec.rb +3 -3
- data/spec/matchers/l33t_spec.rb +15 -13
- data/spec/matchers/repeat_spec.rb +6 -6
- data/spec/matchers/sequences_spec.rb +5 -5
- data/spec/matchers/spatial_spec.rb +8 -8
- data/spec/matchers/year_spec.rb +3 -3
- data/spec/omnimatch_spec.rb +2 -2
- data/spec/scoring/crack_time_spec.rb +13 -13
- data/spec/scoring/entropy_spec.rb +28 -25
- data/spec/scoring/math_spec.rb +22 -18
- data/spec/support/matcher.rb +1 -1
- data/spec/tester_spec.rb +99 -0
- data/spec/zxcvbn_spec.rb +14 -39
- data/zxcvbn-ruby.gemspec +11 -0
- metadata +34 -29
@@ -5,14 +5,14 @@ describe Zxcvbn::Matchers::Repeat do
|
|
5
5
|
let(:matches) { matcher.matches('bbbbbtestingaaa') }
|
6
6
|
|
7
7
|
it 'sets the pattern name' do
|
8
|
-
matches.all? { |m| m.pattern == 'repeat' }.
|
8
|
+
expect(matches.all? { |m| m.pattern == 'repeat' }).to eql(true)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'finds the repeated patterns' do
|
12
|
-
matches.count.
|
13
|
-
matches[0].token.
|
14
|
-
matches[0].repeated_char.
|
15
|
-
matches[1].token.
|
16
|
-
matches[1].repeated_char.
|
12
|
+
expect(matches.count).to eq 2
|
13
|
+
expect(matches[0].token).to eq 'bbbbb'
|
14
|
+
expect(matches[0].repeated_char).to eq 'b'
|
15
|
+
expect(matches[1].token).to eq 'aaa'
|
16
|
+
expect(matches[1].repeated_char).to eq 'a'
|
17
17
|
end
|
18
18
|
end
|
@@ -5,17 +5,17 @@ describe Zxcvbn::Matchers::Sequences do
|
|
5
5
|
let(:matches) { matcher.matches('abcde87654') }
|
6
6
|
|
7
7
|
it 'sets the pattern name' do
|
8
|
-
matches.all? { |m| m.pattern == 'sequence' }.
|
8
|
+
expect(matches.all? { |m| m.pattern == 'sequence' }).to eql(true)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'finds the correct matches' do
|
12
|
-
matches.count.
|
13
|
-
matches[0].token.
|
14
|
-
matches[1].token.
|
12
|
+
expect(matches.count).to eq(2)
|
13
|
+
expect(matches[0].token).to eq 'abcde'
|
14
|
+
expect(matches[1].token).to eq '87654'
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'finds overlapping matches' do
|
18
18
|
matches = matcher.matches('abcba')
|
19
|
-
matches.map(&:token).
|
19
|
+
expect(matches.map(&:token)).to eq ['abc', 'cba']
|
20
20
|
end
|
21
21
|
end
|
@@ -2,19 +2,19 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Zxcvbn::Matchers::Spatial do
|
4
4
|
let(:matcher) { Zxcvbn::Matchers::Spatial.new(graphs) }
|
5
|
-
let(:graphs) { Zxcvbn::
|
5
|
+
let(:graphs) { Zxcvbn::Data.new.adjacency_graphs }
|
6
6
|
|
7
7
|
describe '#matches' do
|
8
8
|
let(:matches) { matcher.matches('rtyikm') }
|
9
9
|
|
10
10
|
it 'finds the correct of matches' do
|
11
|
-
matches.count.
|
12
|
-
matches[0].token.
|
13
|
-
matches[0].graph.
|
14
|
-
matches[1].token.
|
15
|
-
matches[1].graph.
|
16
|
-
matches[2].token.
|
17
|
-
matches[2].graph.
|
11
|
+
expect(matches.count).to eq 3
|
12
|
+
expect(matches[0].token).to eq 'rty'
|
13
|
+
expect(matches[0].graph).to eq 'qwerty'
|
14
|
+
expect(matches[1].token).to eq 'ikm'
|
15
|
+
expect(matches[1].graph).to eq 'qwerty'
|
16
|
+
expect(matches[2].token).to eq 'yik'
|
17
|
+
expect(matches[2].graph).to eq 'dvorak'
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
data/spec/matchers/year_spec.rb
CHANGED
@@ -5,11 +5,11 @@ describe Zxcvbn::Matchers::Year do
|
|
5
5
|
let(:matches) { matcher.matches('testing1998') }
|
6
6
|
|
7
7
|
it 'sets the pattern name' do
|
8
|
-
matches.all? { |m| m.pattern == 'year' }.
|
8
|
+
expect(matches.all? { |m| m.pattern == 'year' }).to eql(true)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'finds the correct matches' do
|
12
|
-
matches.count.
|
13
|
-
matches[0].token.
|
12
|
+
expect(matches.count).to eq(1)
|
13
|
+
expect(matches[0].token).to eq '1998'
|
14
14
|
end
|
15
15
|
end
|
data/spec/omnimatch_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Zxcvbn::Omnimatch do
|
4
4
|
before(:all) do
|
5
|
-
@omnimatch = described_class.new
|
5
|
+
@omnimatch = described_class.new(Zxcvbn::Data.new)
|
6
6
|
end
|
7
7
|
|
8
8
|
def omnimatch(password)
|
@@ -18,7 +18,7 @@ describe Zxcvbn::Omnimatch do
|
|
18
18
|
js_results = js_omnimatch(password)
|
19
19
|
ruby_results = omnimatch(password)
|
20
20
|
|
21
|
-
ruby_results.
|
21
|
+
expect(ruby_results).to match_js_results js_results
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -5,38 +5,38 @@ describe Zxcvbn::CrackTime do
|
|
5
5
|
|
6
6
|
describe '#entropy_to_crack_time' do
|
7
7
|
specify do
|
8
|
-
entropy_to_crack_time(15.433976574415976).
|
8
|
+
expect(entropy_to_crack_time(15.433976574415976)).to eq 2.2134000000000014
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
describe '#crack_time_to_score' do
|
13
13
|
context 'crack time less than 10 to the power 2' do
|
14
14
|
it 'returns 0' do
|
15
|
-
crack_time_to_score(90).
|
15
|
+
expect(crack_time_to_score(90)).to eq 0
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
context 'crack time in between 10**2 and 10**4' do
|
20
20
|
it 'returns 1' do
|
21
|
-
crack_time_to_score(5000).
|
21
|
+
expect(crack_time_to_score(5000)).to eq 1
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
context 'crack time in between 10**4 and 10**6' do
|
26
26
|
it 'returns 2' do
|
27
|
-
crack_time_to_score(500_000).
|
27
|
+
expect(crack_time_to_score(500_000)).to eq 2
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
context 'crack time in between 10**6 and 10**8' do
|
32
32
|
it 'returns 3' do
|
33
|
-
crack_time_to_score(50_000_000).
|
33
|
+
expect(crack_time_to_score(50_000_000)).to eq 3
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
context 'crack time above 10**8' do
|
38
38
|
it 'returns 4' do
|
39
|
-
crack_time_to_score(110_000_000).
|
39
|
+
expect(crack_time_to_score(110_000_000)).to eq 4
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -52,7 +52,7 @@ describe Zxcvbn::CrackTime do
|
|
52
52
|
context 'when less than a minute' do
|
53
53
|
it 'should return instant' do
|
54
54
|
[0, minute_to_seconds - 1].each do |seconds|
|
55
|
-
display_time(seconds).
|
55
|
+
expect(display_time(seconds)).to eql 'instant'
|
56
56
|
end
|
57
57
|
end
|
58
58
|
end
|
@@ -60,7 +60,7 @@ describe Zxcvbn::CrackTime do
|
|
60
60
|
context 'when less than an hour' do
|
61
61
|
it 'should return a readable time in minutes' do
|
62
62
|
[60, (hour_to_seconds - 1)].each do |seconds|
|
63
|
-
display_time(seconds).
|
63
|
+
expect(display_time(seconds)).to match(/[0-9]+ minutes$/)
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
@@ -68,7 +68,7 @@ describe Zxcvbn::CrackTime do
|
|
68
68
|
context 'when less than a day' do
|
69
69
|
it 'should return a readable time in hours' do
|
70
70
|
[hour_to_seconds, (day_to_seconds - 1)].each do |seconds|
|
71
|
-
display_time(seconds).
|
71
|
+
expect(display_time(seconds)).to match(/[0-9]+ hours$/)
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -76,7 +76,7 @@ describe Zxcvbn::CrackTime do
|
|
76
76
|
context 'when less than 31 days' do
|
77
77
|
it 'should return a readable time in days' do
|
78
78
|
[day_to_seconds, month_to_seconds - 1].each do |seconds|
|
79
|
-
display_time(seconds).
|
79
|
+
expect(display_time(seconds)).to match(/[0-9]+ days$/)
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
@@ -84,7 +84,7 @@ describe Zxcvbn::CrackTime do
|
|
84
84
|
context 'when less than 1 year' do
|
85
85
|
it 'should return a readable time in days' do
|
86
86
|
[month_to_seconds, (year_to_seconds - 1)].each do |seconds|
|
87
|
-
display_time(seconds).
|
87
|
+
expect(display_time(seconds)).to match(/[0-9]+ months$/)
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
@@ -92,14 +92,14 @@ describe Zxcvbn::CrackTime do
|
|
92
92
|
context 'when less than a century' do
|
93
93
|
it 'should return a readable time in days' do
|
94
94
|
[year_to_seconds, (century_to_seconds - 1)].each do |seconds|
|
95
|
-
display_time(seconds).
|
95
|
+
expect(display_time(seconds)).to match(/[0-9]+ years$/)
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
100
100
|
context 'when a century or more' do
|
101
101
|
it 'should return centuries' do
|
102
|
-
display_time(century_to_seconds).
|
102
|
+
expect(display_time(century_to_seconds)).to eql 'centuries'
|
103
103
|
end
|
104
104
|
end
|
105
105
|
end
|
@@ -6,13 +6,16 @@ describe Zxcvbn::Entropy do
|
|
6
6
|
let(:entropy) {
|
7
7
|
Class.new do
|
8
8
|
include Zxcvbn::Entropy
|
9
|
+
def data
|
10
|
+
Zxcvbn::Data.new
|
11
|
+
end
|
9
12
|
end.new
|
10
13
|
}
|
11
14
|
|
12
15
|
describe '#repeat_entropy' do
|
13
16
|
it 'returns the correct value' do
|
14
17
|
match = Zxcvbn::Match.new(:token => '2222')
|
15
|
-
entropy.repeat_entropy(match).
|
18
|
+
expect(entropy.repeat_entropy(match)).to eq 5.321928094887363
|
16
19
|
end
|
17
20
|
end
|
18
21
|
|
@@ -24,7 +27,7 @@ describe Zxcvbn::Entropy do
|
|
24
27
|
let(:token) { token }
|
25
28
|
|
26
29
|
it 'returns the correct value' do
|
27
|
-
entropy.sequence_entropy(match).
|
30
|
+
expect(entropy.sequence_entropy(match)).to eq 3.807354922057604
|
28
31
|
end
|
29
32
|
end
|
30
33
|
end
|
@@ -33,7 +36,7 @@ describe Zxcvbn::Entropy do
|
|
33
36
|
let(:token) { '23456' }
|
34
37
|
|
35
38
|
it 'returns the correct value' do
|
36
|
-
entropy.sequence_entropy(match).
|
39
|
+
expect(entropy.sequence_entropy(match)).to eq 5.643856189774725
|
37
40
|
end
|
38
41
|
end
|
39
42
|
|
@@ -41,7 +44,7 @@ describe Zxcvbn::Entropy do
|
|
41
44
|
let(:token) { 'bcdef' }
|
42
45
|
|
43
46
|
it 'returns the correct value' do
|
44
|
-
entropy.sequence_entropy(match).
|
47
|
+
expect(entropy.sequence_entropy(match)).to eq 7.022367813028454
|
45
48
|
end
|
46
49
|
end
|
47
50
|
|
@@ -49,7 +52,7 @@ describe Zxcvbn::Entropy do
|
|
49
52
|
let(:token) { 'BCDEF' }
|
50
53
|
|
51
54
|
it 'returns the correct value' do
|
52
|
-
entropy.sequence_entropy(match).
|
55
|
+
expect(entropy.sequence_entropy(match)).to eq 8.022367813028454
|
53
56
|
end
|
54
57
|
end
|
55
58
|
|
@@ -58,7 +61,7 @@ describe Zxcvbn::Entropy do
|
|
58
61
|
let(:token) { 'bcdef' }
|
59
62
|
|
60
63
|
it 'returns the correct value' do
|
61
|
-
entropy.sequence_entropy(match).
|
64
|
+
expect(entropy.sequence_entropy(match)).to eq 8.022367813028454
|
62
65
|
end
|
63
66
|
end
|
64
67
|
end
|
@@ -66,13 +69,13 @@ describe Zxcvbn::Entropy do
|
|
66
69
|
describe '#digits_entropy' do
|
67
70
|
it 'returns the correct value' do
|
68
71
|
match = Zxcvbn::Match.new(:token => '12345678')
|
69
|
-
entropy.digits_entropy(match).
|
72
|
+
expect(entropy.digits_entropy(match)).to eq 26.5754247590989
|
70
73
|
end
|
71
74
|
end
|
72
75
|
|
73
76
|
describe '#year_entropy' do
|
74
77
|
it 'returns the correct value' do
|
75
|
-
entropy.year_entropy(nil).
|
78
|
+
expect(entropy.year_entropy(nil)).to eq 6.894817763307944
|
76
79
|
end
|
77
80
|
end
|
78
81
|
|
@@ -80,21 +83,21 @@ describe Zxcvbn::Entropy do
|
|
80
83
|
context 'with a two digit year' do
|
81
84
|
it 'returns the correct value' do
|
82
85
|
match = Zxcvbn::Match.new(:year => 98)
|
83
|
-
entropy.date_entropy(match).
|
86
|
+
expect(entropy.date_entropy(match)).to eq 15.183015000882756
|
84
87
|
end
|
85
88
|
end
|
86
89
|
|
87
90
|
context 'with a four digit year' do
|
88
91
|
it 'returns the correct value' do
|
89
92
|
match = Zxcvbn::Match.new(:year => 2012)
|
90
|
-
entropy.date_entropy(match).
|
93
|
+
expect(entropy.date_entropy(match)).to eq 15.433976574415976
|
91
94
|
end
|
92
95
|
end
|
93
96
|
|
94
97
|
context 'with a separator' do
|
95
98
|
it 'returns the correct value' do
|
96
99
|
match = Zxcvbn::Match.new(:year => 2012, :separator => '/')
|
97
|
-
entropy.date_entropy(match).
|
100
|
+
expect(entropy.date_entropy(match)).to eq 17.433976574415976
|
98
101
|
end
|
99
102
|
end
|
100
103
|
end
|
@@ -109,42 +112,42 @@ describe Zxcvbn::Entropy do
|
|
109
112
|
let(:token) { 'you' }
|
110
113
|
let(:rank) { 1 }
|
111
114
|
|
112
|
-
specify { calculated_entropy.
|
115
|
+
specify { expect(calculated_entropy).to eq 0 }
|
113
116
|
end
|
114
117
|
|
115
118
|
context 'with all upper case characters' do
|
116
119
|
let(:token) { 'YOU' }
|
117
120
|
let(:rank) { 1 }
|
118
121
|
|
119
|
-
specify { calculated_entropy.
|
122
|
+
specify { expect(calculated_entropy).to eq 1 }
|
120
123
|
end
|
121
124
|
|
122
125
|
context 'starting with uppercase' do
|
123
126
|
let(:token) { 'You' }
|
124
127
|
let(:rank) { 1 }
|
125
128
|
|
126
|
-
specify { calculated_entropy.
|
129
|
+
specify { expect(calculated_entropy).to eq 1 }
|
127
130
|
end
|
128
131
|
|
129
132
|
context 'starting with uppercase' do
|
130
133
|
let(:token) { 'yoU' }
|
131
134
|
let(:rank) { 1 }
|
132
135
|
|
133
|
-
specify { calculated_entropy.
|
136
|
+
specify { expect(calculated_entropy).to eq 1 }
|
134
137
|
end
|
135
138
|
|
136
139
|
context 'mixed upper and lower' do
|
137
140
|
let(:token) { 'tEsTiNg' }
|
138
141
|
let(:rank) { 1 }
|
139
142
|
|
140
|
-
specify { calculated_entropy.
|
143
|
+
specify { expect(calculated_entropy).to eq 6 }
|
141
144
|
end
|
142
145
|
|
143
146
|
context 'starting with digits' do
|
144
147
|
let(:token) { '12345' }
|
145
148
|
let(:rank) { 1 }
|
146
149
|
|
147
|
-
specify { calculated_entropy.
|
150
|
+
specify { expect(calculated_entropy).to eq 0 }
|
148
151
|
end
|
149
152
|
|
150
153
|
context 'extra l33t entropy' do
|
@@ -153,7 +156,7 @@ describe Zxcvbn::Entropy do
|
|
153
156
|
let(:l33t) { true }
|
154
157
|
let(:sub) { {'3' => 'e', '0' => 'o'} }
|
155
158
|
|
156
|
-
specify { calculated_entropy.
|
159
|
+
specify { expect(calculated_entropy).to eq 1 }
|
157
160
|
end
|
158
161
|
end
|
159
162
|
|
@@ -163,8 +166,8 @@ describe Zxcvbn::Entropy do
|
|
163
166
|
context 'when keyboard is qwerty' do
|
164
167
|
it 'should return the correct entropy' do
|
165
168
|
match.graph = 'qwerty'
|
166
|
-
|
167
|
-
entropy.spatial_entropy(match).
|
169
|
+
|
170
|
+
expect(entropy.spatial_entropy(match)).to eql 11.562242424221074
|
168
171
|
end
|
169
172
|
end
|
170
173
|
|
@@ -172,7 +175,7 @@ describe Zxcvbn::Entropy do
|
|
172
175
|
it 'should return the correct entropy' do
|
173
176
|
match.graph = 'dvorak'
|
174
177
|
|
175
|
-
entropy.spatial_entropy(match).
|
178
|
+
expect(entropy.spatial_entropy(match)).to eql 11.562242424221074
|
176
179
|
end
|
177
180
|
end
|
178
181
|
|
@@ -180,7 +183,7 @@ describe Zxcvbn::Entropy do
|
|
180
183
|
it 'should return the correct entropy' do
|
181
184
|
match.graph = 'keypad'
|
182
185
|
|
183
|
-
entropy.spatial_entropy(match).
|
186
|
+
expect(entropy.spatial_entropy(match)).to eql 9.05528243550119
|
184
187
|
end
|
185
188
|
end
|
186
189
|
|
@@ -188,7 +191,7 @@ describe Zxcvbn::Entropy do
|
|
188
191
|
it 'should return the correct entropy' do
|
189
192
|
match.turns = 5
|
190
193
|
|
191
|
-
entropy.spatial_entropy(match).
|
194
|
+
expect(entropy.spatial_entropy(match)).to eql 21.761397858718993
|
192
195
|
end
|
193
196
|
end
|
194
197
|
|
@@ -196,7 +199,7 @@ describe Zxcvbn::Entropy do
|
|
196
199
|
it 'should return the correct entropy' do
|
197
200
|
match.shiffted_count = 5
|
198
201
|
|
199
|
-
entropy.spatial_entropy(match).
|
202
|
+
expect(entropy.spatial_entropy(match)).to eql 9.05528243550119
|
200
203
|
end
|
201
204
|
end
|
202
205
|
|
@@ -205,7 +208,7 @@ describe Zxcvbn::Entropy do
|
|
205
208
|
match.shiffted_count = 5
|
206
209
|
match.turns = 5
|
207
210
|
|
208
|
-
entropy.spatial_entropy(match).
|
211
|
+
expect(entropy.spatial_entropy(match)).to eql 21.761397858718993
|
209
212
|
end
|
210
213
|
end
|
211
214
|
end
|
data/spec/scoring/math_spec.rb
CHANGED
@@ -3,10 +3,14 @@ require 'spec_helper'
|
|
3
3
|
describe Zxcvbn::Math do
|
4
4
|
include Zxcvbn::Math
|
5
5
|
|
6
|
+
def data
|
7
|
+
Zxcvbn::Data.new
|
8
|
+
end
|
9
|
+
|
6
10
|
describe '#bruteforce_cardinality' do
|
7
11
|
context 'when empty password' do
|
8
12
|
it 'should return 0 if empty password' do
|
9
|
-
bruteforce_cardinality('').
|
13
|
+
expect(bruteforce_cardinality('')).to eql 0
|
10
14
|
end
|
11
15
|
end
|
12
16
|
|
@@ -14,7 +18,7 @@ describe Zxcvbn::Math do
|
|
14
18
|
context 'and a digit' do
|
15
19
|
it 'should return 10' do
|
16
20
|
(0..9).each do |digit|
|
17
|
-
bruteforce_cardinality(digit.to_s).
|
21
|
+
expect(bruteforce_cardinality(digit.to_s)).to eql 10
|
18
22
|
end
|
19
23
|
end
|
20
24
|
end
|
@@ -22,7 +26,7 @@ describe Zxcvbn::Math do
|
|
22
26
|
context 'and an upper case character' do
|
23
27
|
it 'should return 26' do
|
24
28
|
('A'..'Z').each do |character|
|
25
|
-
bruteforce_cardinality(character).
|
29
|
+
expect(bruteforce_cardinality(character)).to eql 26
|
26
30
|
end
|
27
31
|
end
|
28
32
|
end
|
@@ -30,7 +34,7 @@ describe Zxcvbn::Math do
|
|
30
34
|
context 'and a lower case character' do
|
31
35
|
it 'should return 26' do
|
32
36
|
('a'..'z').each do |character|
|
33
|
-
bruteforce_cardinality(character).
|
37
|
+
expect(bruteforce_cardinality(character)).to eql 26
|
34
38
|
end
|
35
39
|
end
|
36
40
|
end
|
@@ -38,7 +42,7 @@ describe Zxcvbn::Math do
|
|
38
42
|
context 'and a symbol' do
|
39
43
|
it 'should return 33' do
|
40
44
|
%w|/ [ ` {|.each do |symbol|
|
41
|
-
bruteforce_cardinality(symbol).
|
45
|
+
expect(bruteforce_cardinality(symbol)).to eql 33
|
42
46
|
end
|
43
47
|
end
|
44
48
|
end
|
@@ -47,31 +51,31 @@ describe Zxcvbn::Math do
|
|
47
51
|
context 'when password is more than one character long' do
|
48
52
|
context 'and only digits' do
|
49
53
|
it 'should return 10' do
|
50
|
-
bruteforce_cardinality('123456789').
|
54
|
+
expect(bruteforce_cardinality('123456789')).to eql 10
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
54
58
|
context 'and only lowercase characters' do
|
55
59
|
it 'should return 26' do
|
56
|
-
bruteforce_cardinality('password').
|
60
|
+
expect(bruteforce_cardinality('password')).to eql 26
|
57
61
|
end
|
58
62
|
end
|
59
63
|
|
60
64
|
context 'and only uppercase characters' do
|
61
65
|
it 'should return 26' do
|
62
|
-
bruteforce_cardinality('PASSWORD').
|
66
|
+
expect(bruteforce_cardinality('PASSWORD')).to eql 26
|
63
67
|
end
|
64
68
|
end
|
65
69
|
|
66
70
|
context 'and only symbols' do
|
67
71
|
it 'should return 33' do
|
68
|
-
bruteforce_cardinality('/ [ ` {').
|
72
|
+
expect(bruteforce_cardinality('/ [ ` {')).to eql 33
|
69
73
|
end
|
70
74
|
end
|
71
75
|
|
72
76
|
context 'and a mixed of character types' do
|
73
77
|
it 'should add up every character type cardinality' do
|
74
|
-
bruteforce_cardinality('p1SsWorD!').
|
78
|
+
expect(bruteforce_cardinality('p1SsWorD!')).to eql 95
|
75
79
|
end
|
76
80
|
end
|
77
81
|
end
|
@@ -80,25 +84,25 @@ describe Zxcvbn::Math do
|
|
80
84
|
describe '#average_degree_for_graph' do
|
81
85
|
context 'when keyboard is qwerty' do
|
82
86
|
it 'returns the correct average degree over all keys' do
|
83
|
-
average_degree_for_graph('qwerty').
|
87
|
+
expect(average_degree_for_graph('qwerty')).to eql 4.595744680851064
|
84
88
|
end
|
85
89
|
end
|
86
90
|
|
87
91
|
context 'when keyboard is dvorak' do
|
88
92
|
it 'returns the correct average degree over all keys' do
|
89
|
-
average_degree_for_graph('dvorak').
|
93
|
+
expect(average_degree_for_graph('dvorak')).to eql 4.595744680851064
|
90
94
|
end
|
91
95
|
end
|
92
96
|
|
93
97
|
context 'when keyboard is keypad' do
|
94
98
|
it 'returns the correct average degree over all keys' do
|
95
|
-
average_degree_for_graph('keypad').
|
99
|
+
expect(average_degree_for_graph('keypad')).to eql 5.066666666666666
|
96
100
|
end
|
97
101
|
end
|
98
102
|
|
99
103
|
context 'when keyboard is mac keypad' do
|
100
104
|
it 'returns the correct average degree over all keys' do
|
101
|
-
average_degree_for_graph('mac_keypad').
|
105
|
+
expect(average_degree_for_graph('mac_keypad')).to eql 5.25
|
102
106
|
end
|
103
107
|
end
|
104
108
|
end
|
@@ -106,25 +110,25 @@ describe Zxcvbn::Math do
|
|
106
110
|
describe '#starting_positions_for_graph' do
|
107
111
|
context 'when keyboard is qwerty' do
|
108
112
|
it 'returns the correct average degree over all keys' do
|
109
|
-
starting_positions_for_graph('qwerty').
|
113
|
+
expect(starting_positions_for_graph('qwerty')).to eql 94
|
110
114
|
end
|
111
115
|
end
|
112
116
|
|
113
117
|
context 'when keyboard is dvorak' do
|
114
118
|
it 'returns the correct average degree over all keys' do
|
115
|
-
starting_positions_for_graph('dvorak').
|
119
|
+
expect(starting_positions_for_graph('dvorak')).to eql 94
|
116
120
|
end
|
117
121
|
end
|
118
122
|
|
119
123
|
context 'when keyboard is keypad' do
|
120
124
|
it 'returns the correct average degree over all keys' do
|
121
|
-
starting_positions_for_graph('keypad').
|
125
|
+
expect(starting_positions_for_graph('keypad')).to eql 15
|
122
126
|
end
|
123
127
|
end
|
124
128
|
|
125
129
|
context 'when keyboard is mac keypad' do
|
126
130
|
it 'returns the correct average degree over all keys' do
|
127
|
-
starting_positions_for_graph('mac_keypad').
|
131
|
+
expect(starting_positions_for_graph('mac_keypad')).to eql 16
|
128
132
|
end
|
129
133
|
end
|
130
134
|
end
|