zxcvbn 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eb6ab0f91ff1467a007376b75b52cce93132791bb2a0efe5b838d28a0300ffff
4
- data.tar.gz: 0373b8736e6a33cf27d0f347f5a81e7030638c9f258b921cfa200dc8ed1d701f
3
+ metadata.gz: 109b1843277c9742ff72f5a6fabda24301fcc6b37d2cdd2075cea0f7e2c91926
4
+ data.tar.gz: d306b716657970d9f14525e5a4eaa0e8e19c1a21183fb09ff0f7ebb488f81337
5
5
  SHA512:
6
- metadata.gz: 70cb61b0c0cc538a67f6bc9235cb161b2161deabc23d755fdc0a1a3b2b689e78e726ebaa6a357c92e0e0a7d9d3e7f185924f4affffe289864e4230c374bab7a1
7
- data.tar.gz: 50af415a3ffa438828916d21664170944cf8a50a3cdf5613c96e1056282c44a9f4a03e52d936e932d99b47ed9675ec9ff7ea836acaf4f9d7c568dc6a29915a55
6
+ metadata.gz: 6bd52c6440b10692b22a3c1b10e13fd9c84305ca66c455f90361fb5d20962926676b19402c968dc4d1a17be45d95c6da05828fc2f9e7244b0e9555cf9984203d
7
+ data.tar.gz: 30189e55b622422c4222034eaf5212f9ff2f7d22a9dd5da35bc724372681b43d1e542b91805310943e8a2be37481fd8447c99b9d94924a3cd11d40b9c0107873
data/.rubocop.yml CHANGED
@@ -1,5 +1,30 @@
1
1
  AllCops:
2
2
  TargetRubyVersion: 2.5
3
+ NewCops: enable
4
+
5
+ Layout/EndAlignment:
6
+ EnforcedStyleAlignWith: start_of_line
7
+
8
+ Layout/LineLength:
9
+ Max: 120
10
+
11
+ Lint/UnderscorePrefixedVariableName:
12
+ Enabled: false
13
+
14
+ Metrics:
15
+ Enabled: false
16
+
17
+ Naming/VariableNumber:
18
+ Enabled: false
19
+
20
+ Style/Documentation:
21
+ Enabled: false
22
+
23
+ Style/Next:
24
+ Enabled: false
25
+
26
+ Style/NumericPredicate:
27
+ Enabled: false
3
28
 
4
29
  Style/StringLiterals:
5
30
  Enabled: true
@@ -9,5 +34,11 @@ Style/StringLiteralsInInterpolation:
9
34
  Enabled: true
10
35
  EnforcedStyle: double_quotes
11
36
 
12
- Layout/LineLength:
13
- Max: 120
37
+ Style/NegatedIf:
38
+ Enabled: false
39
+
40
+ Style/SymbolArray:
41
+ Enabled: false
42
+
43
+ Style/WordArray:
44
+ Enabled: false
data/.travis.yml CHANGED
@@ -2,5 +2,5 @@
2
2
  language: ruby
3
3
  cache: bundler
4
4
  rvm:
5
- - 2.6.6
5
+ - 2.5.9
6
6
  before_install: gem install bundler -v 2.2.15
data/Gemfile CHANGED
@@ -6,10 +6,10 @@ source "https://rubygems.org"
6
6
  gemspec
7
7
 
8
8
  group :development do
9
+ gem "mini_racer"
9
10
  gem "rake", "~> 13.0"
10
11
  gem "rspec", "~> 3.0"
11
12
  gem "rubocop", "~> 1.7"
12
- gem 'mini_racer'
13
13
 
14
14
  gem "pry"
15
15
  gem "pry-byebug"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- zxcvbn (0.1.2)
4
+ zxcvbn (0.1.4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/bin/console CHANGED
@@ -14,5 +14,5 @@ require "zxcvbn"
14
14
  # require "irb"
15
15
  # IRB.start(__FILE__)
16
16
 
17
- require 'pry'
17
+ require "pry"
18
18
  Pry.start("main")
data/lib/zxcvbn.rb CHANGED
@@ -14,13 +14,11 @@ module Zxcvbn
14
14
  def self.zxcvbn(password, user_inputs = [])
15
15
  start = (Time.now.to_f * 1000).to_i
16
16
  # reset the user inputs matcher on a per-request basis to keep things stateless
17
- sanitized_inputs = [];
17
+ sanitized_inputs = []
18
18
  user_inputs.each do |arg|
19
- if arg.is_a?(String) || arg.is_a?(Numeric) || arg == true || arg == false
20
- sanitized_inputs << arg.to_s.downcase
21
- end
19
+ sanitized_inputs << arg.to_s.downcase if arg.is_a?(String) || arg.is_a?(Numeric) || arg == true || arg == false
22
20
  end
23
- Matching.set_user_input_dictionary(sanitized_inputs)
21
+ Matching.user_input_dictionary = sanitized_inputs
24
22
  matches = Matching.omnimatch(password)
25
23
  result = Scoring.most_guessable_match_sequence(password, matches)
26
24
  result["calc_time"] = (Time.now.to_f * 1000).to_i - start
@@ -29,6 +27,6 @@ module Zxcvbn
29
27
  result[prop] = val
30
28
  end
31
29
  result["feedback"] = Feedback.get_feedback(result["score"], result["sequence"])
32
- return result
30
+ result
33
31
  end
34
32
  end
@@ -2,10 +2,12 @@
2
2
 
3
3
  # generated by scripts/build_keyboard_adjacency_graphs.py
4
4
  module Zxcvbn
5
+ # rubocop:disable Layout/SpaceInsideArrayLiteralBrackets
6
+ # rubocop:disable Layout/ExtraSpacing
5
7
  ADJACENCY_GRAPHS = {
6
8
  "qwerty" => {
7
9
  "!" => ["`~", nil, nil, "2@", "qQ", nil],
8
- "\"" => [";:", "[{", "]}", nil, nil, "/?"],
10
+ "\"" => [";:", "[{", "]}", nil, nil, "/?"],
9
11
  "#" => ["2@", nil, nil, "4$", "eE", "wW"],
10
12
  "$" => ["3#", nil, nil, "5%", "rR", "eE"],
11
13
  "%" => ["4$", nil, nil, "6^", "tT", "rR"],
@@ -18,7 +20,7 @@ module Zxcvbn
18
20
  "," => ["mM", "kK", "lL", ".>", nil, nil],
19
21
  "-" => ["0)", nil, nil, "=+", "[{", "pP"],
20
22
  "." => [",<", "lL", ";:", "/?", nil, nil],
21
- "/" => [".>", ";:", "'\"", nil, nil, nil],
23
+ "/" => [".>", ";:", "'\"", nil, nil, nil],
22
24
  "0" => ["9(", nil, nil, "-_", "pP", "oO"],
23
25
  "1" => ["`~", nil, nil, "2@", "qQ", nil],
24
26
  "2" => ["1!", nil, nil, "3#", "wW", "qQ"],
@@ -34,7 +36,7 @@ module Zxcvbn
34
36
  "<" => ["mM", "kK", "lL", ".>", nil, nil],
35
37
  "=" => ["-_", nil, nil, nil, "]}", "[{"],
36
38
  ">" => [",<", "lL", ";:", "/?", nil, nil],
37
- "?" => [".>", ";:", "'\"", nil, nil, nil],
39
+ "?" => [".>", ";:", "'\"", nil, nil, nil],
38
40
  "@" => ["1!", nil, nil, "3#", "wW", "qQ"],
39
41
  "A" => [ nil, "qQ", "wW", "sS", "zZ", nil],
40
42
  "B" => ["vV", "gG", "hH", "nN", nil, nil],
@@ -63,8 +65,8 @@ module Zxcvbn
63
65
  "Y" => ["tT", "6^", "7&", "uU", "hH", "gG"],
64
66
  "Z" => [ nil, "aA", "sS", "xX", nil, nil],
65
67
  "[" => ["pP", "-_", "=+", "]}", "'\"", ";:"],
66
- "\\" => ["]}", nil, nil, nil, nil, nil],
67
- "]" => ["[{", "=+", nil, "\\|", nil, "'\""],
68
+ "\\" => ["]}", nil, nil, nil, nil, nil],
69
+ "]" => ["[{", "=+", nil, "\\|", nil, "'\""],
68
70
  "^" => ["5%", nil, nil, "7&", "yY", "tT"],
69
71
  "_" => ["0)", nil, nil, "=+", "[{", "pP"],
70
72
  "`" => [ nil, nil, nil, "1!", nil, nil],
@@ -96,12 +98,12 @@ module Zxcvbn
96
98
  "z" => [ nil, "aA", "sS", "xX", nil, nil],
97
99
  "{" => ["pP", "-_", "=+", "]}", "'\"", ";:"],
98
100
  "|" => ["]}", nil, nil, nil, nil, nil],
99
- "}" => ["[{", "=+", nil, "\\|", nil, "'\""],
101
+ "}" => ["[{", "=+", nil, "\\|", nil, "'\""],
100
102
  "~" => [ nil, nil, nil, "1!", nil, nil]
101
103
  },
102
104
  "dvorak" => {
103
- "!" => ["`~", nil, nil, "2@", "'\"", nil],
104
- "\"" => [ nil, "1!", "2@", ",<", "aA", nil],
105
+ "!" => ["`~", nil, nil, "2@", "'\"", nil],
106
+ "\"" => [ nil, "1!", "2@", ",<", "aA", nil],
105
107
  "#" => ["2@", nil, nil, "4$", ".>", ",<"],
106
108
  "$" => ["3#", nil, nil, "5%", "pP", ".>"],
107
109
  "%" => ["4$", nil, nil, "6^", "yY", "pP"],
@@ -110,13 +112,13 @@ module Zxcvbn
110
112
  "(" => ["8*", nil, nil, "0)", "rR", "cC"],
111
113
  ")" => ["9(", nil, nil, "[{", "lL", "rR"],
112
114
  "*" => ["7&", nil, nil, "9(", "cC", "gG"],
113
- "+" => ["/?", "]}", nil, "\\|", nil, "-_"],
115
+ "+" => ["/?", "]}", nil, "\\|", nil, "-_"],
114
116
  "," => ["'\"", "2@", "3#", ".>", "oO", "aA"],
115
117
  "-" => ["sS", "/?", "=+", nil, nil, "zZ"],
116
118
  "." => [",<", "3#", "4$", "pP", "eE", "oO"],
117
119
  "/" => ["lL", "[{", "]}", "=+", "-_", "sS"],
118
120
  "0" => ["9(", nil, nil, "[{", "lL", "rR"],
119
- "1" => ["`~", nil, nil, "2@", "'\"", nil],
121
+ "1" => ["`~", nil, nil, "2@", "'\"", nil],
120
122
  "2" => ["1!", nil, nil, "3#", ",<", "'\""],
121
123
  "3" => ["2@", nil, nil, "4$", ".>", ",<"],
122
124
  "4" => ["3#", nil, nil, "5%", "pP", ".>"],
@@ -132,7 +134,7 @@ module Zxcvbn
132
134
  ">" => [",<", "3#", "4$", "pP", "eE", "oO"],
133
135
  "?" => ["lL", "[{", "]}", "=+", "-_", "sS"],
134
136
  "@" => ["1!", nil, nil, "3#", ",<", "'\""],
135
- "A" => [ nil, "'\"", ",<", "oO", ";:", nil],
137
+ "A" => [ nil, "'\"", ",<", "oO", ";:", nil],
136
138
  "B" => ["xX", "dD", "hH", "mM", nil, nil],
137
139
  "C" => ["gG", "8*", "9(", "rR", "tT", "hH"],
138
140
  "D" => ["iI", "fF", "gG", "hH", "bB", "xX"],
@@ -159,12 +161,12 @@ module Zxcvbn
159
161
  "Y" => ["pP", "5%", "6^", "fF", "iI", "uU"],
160
162
  "Z" => ["vV", "sS", "-_", nil, nil, nil],
161
163
  "[" => ["0)", nil, nil, "]}", "/?", "lL"],
162
- "\\" => ["=+", nil, nil, nil, nil, nil],
164
+ "\\" => ["=+", nil, nil, nil, nil, nil],
163
165
  "]" => ["[{", nil, nil, nil, "=+", "/?"],
164
166
  "^" => ["5%", nil, nil, "7&", "fF", "yY"],
165
167
  "_" => ["sS", "/?", "=+", nil, nil, "zZ"],
166
168
  "`" => [ nil, nil, nil, "1!", nil, nil],
167
- "a" => [ nil, "'\"", ",<", "oO", ";:", nil],
169
+ "a" => [ nil, "'\"", ",<", "oO", ";:", nil],
168
170
  "b" => ["xX", "dD", "hH", "mM", nil, nil],
169
171
  "c" => ["gG", "8*", "9(", "rR", "tT", "hH"],
170
172
  "d" => ["iI", "fF", "gG", "hH", "bB", "xX"],
@@ -196,39 +198,41 @@ module Zxcvbn
196
198
  "~" => [ nil, nil, nil, "1!", nil, nil]
197
199
  },
198
200
  "keypad" => {
199
- "*" => ["/", nil, nil, nil, "-", "+", "9", "8"],
200
- "+" => ["9", "*", "-", nil, nil, nil, nil, "6"],
201
- "-" => ["*", nil, nil, nil, nil, nil, "+", "9"],
202
- "." => ["0", "2", "3", nil, nil, nil, nil, nil],
203
- "/" => [ nil, nil, nil, nil, "*", "9", "8", "7"],
204
- "0" => [ nil, "1", "2", "3", ".", nil, nil, nil],
205
- "1" => [ nil, nil, "4", "5", "2", "0", nil, nil],
206
- "2" => ["1", "4", "5", "6", "3", ".", "0", nil],
207
- "3" => ["2", "5", "6", nil, nil, nil, ".", "0"],
208
- "4" => [ nil, nil, "7", "8", "5", "2", "1", nil],
201
+ "*" => ["/", nil, nil, nil, "-", "+", "9", "8"],
202
+ "+" => ["9", "*", "-", nil, nil, nil, nil, "6"],
203
+ "-" => ["*", nil, nil, nil, nil, nil, "+", "9"],
204
+ "." => ["0", "2", "3", nil, nil, nil, nil, nil],
205
+ "/" => [nil, nil, nil, nil, "*", "9", "8", "7"],
206
+ "0" => [nil, "1", "2", "3", ".", nil, nil, nil],
207
+ "1" => [nil, nil, "4", "5", "2", "0", nil, nil],
208
+ "2" => ["1", "4", "5", "6", "3", ".", "0", nil],
209
+ "3" => ["2", "5", "6", nil, nil, nil, ".", "0"],
210
+ "4" => [nil, nil, "7", "8", "5", "2", "1", nil],
209
211
  "5" => ["4", "7", "8", "9", "6", "3", "2", "1"],
210
- "6" => ["5", "8", "9", "+", nil, nil, "3", "2"],
211
- "7" => [ nil, nil, nil, "/", "8", "5", "4", nil],
212
- "8" => ["7", nil, "/", "*", "9", "6", "5", "4"],
213
- "9" => ["8", "/", "*", "-", "+", nil, "6", "5"]
212
+ "6" => ["5", "8", "9", "+", nil, nil, "3", "2"],
213
+ "7" => [nil, nil, nil, "/", "8", "5", "4", nil],
214
+ "8" => ["7", nil, "/", "*", "9", "6", "5", "4"],
215
+ "9" => ["8", "/", "*", "-", "+", nil, "6", "5"]
214
216
  },
215
217
  "mac_keypad" => {
216
- "*" => ["/", nil, nil, nil, nil, nil, "-", "9"],
217
- "+" => ["6", "9", "-", nil, nil, nil, nil, "3"],
218
- "-" => ["9", "/", "*", nil, nil, nil, "+", "6"],
219
- "." => ["0", "2", "3", nil, nil, nil, nil, nil],
220
- "/" => ["=", nil, nil, nil, "*", "-", "9", "8"],
221
- "0" => [ nil, "1", "2", "3", ".", nil, nil, nil],
222
- "1" => [ nil, nil, "4", "5", "2", "0", nil, nil],
223
- "2" => ["1", "4", "5", "6", "3", ".", "0", nil],
224
- "3" => ["2", "5", "6", "+", nil, nil, ".", "0"],
225
- "4" => [ nil, nil, "7", "8", "5", "2", "1", nil],
218
+ "*" => ["/", nil, nil, nil, nil, nil, "-", "9"],
219
+ "+" => ["6", "9", "-", nil, nil, nil, nil, "3"],
220
+ "-" => ["9", "/", "*", nil, nil, nil, "+", "6"],
221
+ "." => ["0", "2", "3", nil, nil, nil, nil, nil],
222
+ "/" => ["=", nil, nil, nil, "*", "-", "9", "8"],
223
+ "0" => [nil, "1", "2", "3", ".", nil, nil, nil],
224
+ "1" => [nil, nil, "4", "5", "2", "0", nil, nil],
225
+ "2" => ["1", "4", "5", "6", "3", ".", "0", nil],
226
+ "3" => ["2", "5", "6", "+", nil, nil, ".", "0"],
227
+ "4" => [nil, nil, "7", "8", "5", "2", "1", nil],
226
228
  "5" => ["4", "7", "8", "9", "6", "3", "2", "1"],
227
- "6" => ["5", "8", "9", "-", "+", nil, "3", "2"],
228
- "7" => [ nil, nil, nil, "=", "8", "5", "4", nil],
229
- "8" => ["7", nil, "=", "/", "9", "6", "5", "4"],
229
+ "6" => ["5", "8", "9", "-", "+", nil, "3", "2"],
230
+ "7" => [nil, nil, nil, "=", "8", "5", "4", nil],
231
+ "8" => ["7", nil, "=", "/", "9", "6", "5", "4"],
230
232
  "9" => ["8", "=", "/", "*", "-", "+", "6", "5"],
231
- "=" => [ nil, nil, nil, nil, "/", "9", "8", "7"]
233
+ "=" => [nil, nil, nil, nil, "/", "9", "8", "7"]
232
234
  }
233
- }
235
+ }.freeze
236
+ # rubocop:enable Layout/ExtraSpacing
237
+ # rubocop:enable Layout/SpaceInsideArrayLiteralBrackets
234
238
  end
@@ -3,9 +3,9 @@
3
3
  module Zxcvbn
4
4
  module Feedback
5
5
  DEFAULT_FEEDBACK = {
6
- "warning" => '',
6
+ "warning" => "",
7
7
  "suggestions" => ["Use a few words, avoid common phrases", "No need for symbols, digits, or uppercase letters"]
8
- }
8
+ }.freeze
9
9
 
10
10
  def self.get_feedback(score, sequence)
11
11
  if sequence.empty?
@@ -16,91 +16,94 @@ module Zxcvbn
16
16
  # no feedback if score is good or great.
17
17
  if score > 2
18
18
  return {
19
- "warning" => '',
19
+ "warning" => "",
20
20
  "suggestions" => []
21
21
  }
22
22
  end
23
23
 
24
- longest_match = sequence.max_by{|match| match["token"].length }
24
+ longest_match = sequence.max_by { |match| match["token"].length }
25
25
  feedback = get_match_feedback(longest_match, sequence.size == 1)
26
- extra_feedback = 'Add another word or two. Uncommon words are better.'
27
- if !feedback.nil?
26
+ extra_feedback = "Add another word or two. Uncommon words are better."
27
+ if feedback
28
28
  feedback["suggestions"].unshift(extra_feedback)
29
- if feedback["warning"].nil?
30
- feedback["warning"] = ''
31
- end
29
+ feedback["warning"] = "" if feedback["warning"].nil?
32
30
  else
33
31
  feedback = {
34
- "warning" => '',
32
+ "warning" => "",
35
33
  "suggestions" => [extra_feedback]
36
34
  }
37
35
  end
38
- return feedback
36
+ feedback
39
37
  end
40
38
 
41
39
  def self.get_match_feedback(match, is_sole_match)
42
40
  case match["pattern"]
43
- when 'dictionary'
44
- return get_dictionary_match_feedback(match, is_sole_match)
45
- when 'spatial'
46
- layout = match["graph.upcase"]
47
- warning = match["turns"] == 1 ? 'Straight rows of keys are easy to guess' : 'Short keyboard patterns are easy to guess'
48
- return {
41
+ when "dictionary"
42
+ get_dictionary_match_feedback(match, is_sole_match)
43
+ when "spatial"
44
+ warning = if match["turns"] == 1
45
+ "Straight rows of keys are easy to guess"
46
+ else
47
+ "Short keyboard patterns are easy to guess"
48
+ end
49
+ {
49
50
  "warning" => warning,
50
- "suggestions" => ['Use a longer keyboard pattern with more turns']
51
+ "suggestions" => ["Use a longer keyboard pattern with more turns"]
51
52
  }
52
- when 'repeat'
53
- warning = match["base_token"].length == 1 ? 'Repeats like "aaa" are easy to guess' : 'Repeats like "abcabcabc" are only slightly harder to guess than "abc"'
54
- return {
53
+ when "repeat"
54
+ warning = if match["base_token"].length == 1
55
+ 'Repeats like "aaa" are easy to guess'
56
+ else
57
+ 'Repeats like "abcabcabc" are only slightly harder to guess than "abc"'
58
+ end
59
+ {
55
60
  "warning" => warning,
56
- "suggestions" => ['Avoid repeated words and characters']
61
+ "suggestions" => ["Avoid repeated words and characters"]
57
62
  }
58
- when 'sequence'
59
- return {
63
+ when "sequence"
64
+ {
60
65
  "warning" => "Sequences like abc or 6543 are easy to guess",
61
- "suggestions" => ['Avoid sequences']
66
+ "suggestions" => ["Avoid sequences"]
62
67
  }
63
- when 'regex'
64
- if match["regex_name"] === 'recent_year'
65
- return {
68
+ when "regex"
69
+ if match["regex_name"] == "recent_year"
70
+ {
66
71
  "warning" => "Recent years are easy to guess",
67
- "suggestions" => ['Avoid recent years', 'Avoid years that are associated with you']
72
+ "suggestions" => ["Avoid recent years", "Avoid years that are associated with you"]
68
73
  }
69
74
  end
70
75
  # break
71
- when 'date'
72
- return {
76
+ when "date"
77
+ {
73
78
  "warning" => "Dates are often easy to guess",
74
- "suggestions" => ['Avoid dates and years that are associated with you']
79
+ "suggestions" => ["Avoid dates and years that are associated with you"]
75
80
  }
76
81
  end
77
82
  end
78
83
 
79
84
  def self.get_dictionary_match_feedback(match, is_sole_match)
80
- warning = if match["dictionary_name"] == 'passwords'
85
+ warning = if match["dictionary_name"] == "passwords"
81
86
  if is_sole_match && !match["l33t"] && !match["reversed"]
82
87
  if match["rank"] <= 10
83
- 'This is a top-10 common password'
88
+ "This is a top-10 common password"
84
89
  elsif match["rank"] <= 100
85
- 'This is a top-100 common password'
90
+ "This is a top-100 common password"
86
91
  else
87
- 'This is a very common password'
92
+ "This is a very common password"
88
93
  end
89
94
  elsif match["guesses_log10"] <= 4
90
- 'This is similar to a commonly used password'
91
- end
92
- elsif match["dictionary_name"] == 'english_wikipedia'
93
- if is_sole_match
94
- 'A word by itself is easy to guess'
95
+ "This is similar to a commonly used password"
95
96
  end
96
- elsif ['surnames', 'male_names', 'female_names'].include?(match["dictionary_name"])
97
+ elsif match["dictionary_name"] == "english_wikipedia"
98
+ "A word by itself is easy to guess" if is_sole_match
99
+ elsif ["surnames", "male_names", "female_names"].include?(match["dictionary_name"])
97
100
  if is_sole_match
98
- 'Names and surnames by themselves are easy to guess'
101
+ "Names and surnames by themselves are easy to guess"
99
102
  else
100
- 'Common names and surnames are easy to guess'
103
+ "Common names and surnames are easy to guess"
101
104
  end
102
105
  else
103
- ''
106
+ ""
104
107
  end
105
108
  suggestions = []
106
109
  word = match["token"]
@@ -109,17 +112,12 @@ module Zxcvbn
109
112
  elsif word.match(Scoring::ALL_UPPER) && word.downcase != word
110
113
  suggestions << "All-uppercase is almost as easy to guess as all-lowercase"
111
114
  end
112
- if match["reversed"] && match["token"].length >= 4
113
- suggestions << "Reversed words aren't much harder to guess"
114
- end
115
- if match["l33t"]
116
- suggestions << "Predictable substitutions like '@' instead of 'a' don't help very much"
117
- end
118
- result = {
115
+ suggestions << "Reversed words aren't much harder to guess" if match["reversed"] && match["token"].length >= 4
116
+ suggestions << "Predictable substitutions like '@' instead of 'a' don't help very much" if match["l33t"]
117
+ {
119
118
  "warning" => warning,
120
119
  "suggestions" => suggestions
121
120
  }
122
- return result
123
121
  end
124
122
  end
125
123
  end