zxcvbn-ruby 1.4.0 → 2.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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +67 -1
  3. data/README.md +322 -75
  4. data/data/frequency_lists/english_wikipedia.txt +30000 -0
  5. data/data/frequency_lists/female_names.txt +11 -114
  6. data/data/frequency_lists/male_names.txt +3 -24
  7. data/data/frequency_lists/passwords.txt +29623 -6764
  8. data/data/frequency_lists/surnames.txt +28 -30611
  9. data/data/frequency_lists/{english.txt → us_tv_and_film.txt} +147 -13532
  10. data/lib/zxcvbn/case_helpers.rb +25 -0
  11. data/lib/zxcvbn/clock.rb +6 -0
  12. data/lib/zxcvbn/crack_time.rb +52 -18
  13. data/lib/zxcvbn/data.rb +61 -21
  14. data/lib/zxcvbn/dictionary_ranker.rb +15 -1
  15. data/lib/zxcvbn/feedback.rb +11 -6
  16. data/lib/zxcvbn/feedback_giver.rb +75 -50
  17. data/lib/zxcvbn/guesses.rb +208 -0
  18. data/lib/zxcvbn/match.rb +95 -15
  19. data/lib/zxcvbn/match_builder.rb +15 -0
  20. data/lib/zxcvbn/matchers/date.rb +171 -106
  21. data/lib/zxcvbn/matchers/dictionary.rb +18 -9
  22. data/lib/zxcvbn/matchers/digits.rb +6 -1
  23. data/lib/zxcvbn/matchers/l33t.rb +33 -34
  24. data/lib/zxcvbn/matchers/regex_helpers.rb +14 -6
  25. data/lib/zxcvbn/matchers/repeat.rb +47 -16
  26. data/lib/zxcvbn/matchers/sequences.rb +58 -48
  27. data/lib/zxcvbn/matchers/spatial.rb +22 -6
  28. data/lib/zxcvbn/matchers/year.rb +6 -1
  29. data/lib/zxcvbn/math.rb +15 -28
  30. data/lib/zxcvbn/omnimatch.rb +70 -22
  31. data/lib/zxcvbn/ruby.rb +3 -0
  32. data/lib/zxcvbn/score.rb +34 -10
  33. data/lib/zxcvbn/scorer.rb +148 -75
  34. data/lib/zxcvbn/tester.rb +58 -23
  35. data/lib/zxcvbn/tester_builder.rb +83 -0
  36. data/lib/zxcvbn/trie.rb +21 -0
  37. data/lib/zxcvbn/version.rb +1 -1
  38. data/lib/zxcvbn.rb +47 -7
  39. data/sig/zxcvbn/case_helpers.rbs +5 -0
  40. data/sig/zxcvbn/clock.rbs +5 -0
  41. data/sig/zxcvbn/crack_time.rbs +3 -5
  42. data/sig/zxcvbn/data.rbs +17 -8
  43. data/sig/zxcvbn/feedback.rbs +6 -4
  44. data/sig/zxcvbn/guesses.rbs +36 -0
  45. data/sig/zxcvbn/match.rbs +35 -33
  46. data/sig/zxcvbn/match_builder.rbs +36 -0
  47. data/sig/zxcvbn/matchers/date.rbs +23 -0
  48. data/sig/zxcvbn/matchers/dictionary.rbs +23 -0
  49. data/sig/zxcvbn/matchers/digits.rbs +11 -0
  50. data/sig/zxcvbn/matchers/l33t.rbs +29 -0
  51. data/sig/zxcvbn/matchers/regex_helpers.rbs +7 -0
  52. data/sig/zxcvbn/matchers/repeat.rbs +11 -0
  53. data/sig/zxcvbn/matchers/sequences.rbs +16 -0
  54. data/sig/zxcvbn/matchers/spatial.rbs +15 -0
  55. data/sig/zxcvbn/matchers/year.rbs +11 -0
  56. data/sig/zxcvbn/math.rbs +0 -4
  57. data/sig/zxcvbn/omnimatch.rbs +5 -2
  58. data/sig/zxcvbn/score.rbs +22 -11
  59. data/sig/zxcvbn/scorer.rbs +7 -8
  60. data/sig/zxcvbn/tester.rbs +5 -7
  61. data/sig/zxcvbn/tester_builder.rbs +16 -0
  62. data/sig/zxcvbn/trie.rbs +4 -0
  63. data/sig/zxcvbn.rbs +6 -4
  64. metadata +32 -13
  65. data/lib/zxcvbn/entropy.rb +0 -158
  66. data/lib/zxcvbn/matchers/new_l33t.rb +0 -118
  67. data/lib/zxcvbn/password_strength.rb +0 -27
  68. data/sig/zxcvbn/entropy.rbs +0 -33
  69. data/sig/zxcvbn/password_strength.rbs +0 -10
data/lib/zxcvbn.rb CHANGED
@@ -1,22 +1,62 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pathname'
4
3
  require 'zxcvbn/version'
5
4
  require 'zxcvbn/tester'
5
+ require 'zxcvbn/tester_builder'
6
6
 
7
+ # Ruby port of zxcvbn.js — realistic password strength estimation.
8
+ #
9
+ # Analyses a password against dictionary lists, keyboard patterns, dates,
10
+ # sequences, and repeats to produce a {Score} with guess estimates and
11
+ # human-readable crack-time display strings.
7
12
  module Zxcvbn
8
13
  module_function
9
14
 
10
- DATA_PATH = Pathname(File.expand_path('../data', __dir__))
15
+ # Mutex protecting lazy initialisation of the shared default {Tester}.
16
+ DEFAULT_TESTER_MUTEX = Mutex.new
17
+ private_constant :DEFAULT_TESTER_MUTEX
11
18
 
12
- # Returns a Zxcvbn::Score for the given password
19
+ # Returns a Zxcvbn::Score for the given password.
20
+ #
21
+ # Reuses a shared {Tester} instance across calls. For custom word lists or
22
+ # options, use {.tester_builder} to build a dedicated {Tester}.
23
+ #
24
+ # Raises {PasswordTooLong} (a subclass of +ArgumentError+) if the password
25
+ # exceeds the configured limit (default: 256 characters). Override process-wide
26
+ # via the +ZXCVBN_MAX_PASSWORD_LENGTH+ environment variable; for per-call limits,
27
+ # use {.tester_builder} with {TesterBuilder#max_password_length}.
13
28
  #
14
29
  # Example:
15
30
  #
16
31
  # Zxcvbn.test("password").score #=> 0
17
- def test(password, user_inputs = [], word_lists = {})
18
- tester = Tester.new
19
- tester.add_word_lists(word_lists)
20
- tester.test(password, user_inputs)
32
+ #
33
+ # @param password [String] the password to evaluate
34
+ # @param user_inputs [Array<String>] caller-supplied words to treat as known
35
+ # @return [Score]
36
+ # @raise [PasswordTooLong] if the password exceeds the maximum length
37
+ def test(password, user_inputs = [])
38
+ default_tester.test(password, user_inputs)
39
+ end
40
+
41
+ # Returns a new {TesterBuilder} for constructing a {Tester} with custom
42
+ # word lists and options.
43
+ #
44
+ # Example:
45
+ #
46
+ # tester = Zxcvbn
47
+ # .tester_builder
48
+ # .add_word_list('company', %w[acme corp])
49
+ # .max_password_length(75)
50
+ # .build
51
+ #
52
+ # @return [TesterBuilder]
53
+ def tester_builder
54
+ TesterBuilder.new
55
+ end
56
+
57
+ # @return [Tester] the shared default tester, constructed on first call
58
+ def default_tester
59
+ DEFAULT_TESTER_MUTEX.synchronize { @default_tester ||= tester_builder.build }
21
60
  end
61
+ private_class_method :default_tester
22
62
  end
@@ -0,0 +1,5 @@
1
+ module Zxcvbn
2
+ module CaseHelpers
3
+ def self?.downcase_preserving_length: (String string) -> String
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Zxcvbn
2
+ module Clock
3
+ def self.realtime: () { () -> void } -> Float
4
+ end
5
+ end
@@ -1,12 +1,10 @@
1
1
  module Zxcvbn
2
2
  module CrackTime
3
- SINGLE_GUESS: Float
4
- NUM_ATTACKERS: Integer
5
- SECONDS_PER_GUESS: Float
3
+ ATTACK_SCENARIOS: Hash[String, Float]
6
4
 
7
- def entropy_to_crack_time: (Numeric entropy) -> Float
5
+ def estimate_attack_times: (Numeric guesses) -> { crack_times_seconds: Hash[String, Float], crack_times_display: Hash[String, String] }
8
6
 
9
- def crack_time_to_score: (Numeric seconds) -> Integer
7
+ def guesses_to_score: (Numeric guesses) -> Integer
10
8
 
11
9
  def display_time: (Numeric seconds) -> String
12
10
  end
data/sig/zxcvbn/data.rbs CHANGED
@@ -4,27 +4,36 @@ module Zxcvbn
4
4
  type adjacency_graph = Hash[String, Array[String?]]
5
5
  type graph_stats = Hash[String, { average_degree: Float, starting_positions: Integer }]
6
6
 
7
- @ranked_dictionaries: Hash[String, ranked_dictionary]
7
+ class Dictionaries
8
+ attr_reader ranked: Hash[String, ranked_dictionary]
9
+ attr_reader tries: Hash[String, Trie]
10
+
11
+ def initialize: (ranked: Hash[String, ranked_dictionary], tries: Hash[String, Trie]) -> void
12
+ end
13
+
14
+ RESERVED_NAMES: Array[String]
15
+
16
+ @dictionaries: Dictionaries
8
17
  @adjacency_graphs: Hash[String, adjacency_graph]
9
- @dictionary_tries: Hash[String, Trie]
10
18
  @graph_stats: graph_stats
11
19
 
12
- attr_reader ranked_dictionaries: Hash[String, ranked_dictionary]
20
+ attr_reader dictionaries: Dictionaries
13
21
  attr_reader adjacency_graphs: Hash[String, adjacency_graph]
14
- attr_reader dictionary_tries: Hash[String, Trie]
15
22
  attr_reader graph_stats: graph_stats
16
23
 
24
+ def ranked_dictionaries: () -> Hash[String, ranked_dictionary]
25
+
26
+ def dictionary_tries: () -> Hash[String, Trie]
27
+
17
28
  def initialize: () -> void
18
29
 
19
- def add_word_list: (String name, Array[String] list) -> void
30
+ def add_word_list: (String name, Array[untyped] list) -> void
20
31
 
21
32
  private
22
33
 
23
34
  def read_word_list: (String file) -> Array[String]
24
35
 
25
- def build_tries: () -> Hash[String, Trie]
26
-
27
- def build_trie: (ranked_dictionary ranked_dictionary) -> Trie
36
+ def build_tries: (Hash[String, ranked_dictionary] ranked) -> Hash[String, Trie]
28
37
 
29
38
  def compute_graph_stats: () -> graph_stats
30
39
  end
@@ -1,8 +1,10 @@
1
1
  module Zxcvbn
2
- class Feedback
3
- attr_accessor warning: String?
4
- attr_accessor suggestions: Array[String]
2
+ class Feedback < Data
3
+ attr_reader warning: String
4
+ attr_reader suggestions: Array[String]
5
5
 
6
- def initialize: (?warning: String?, ?suggestions: Array[String]) -> void
6
+ def initialize: (?warning: String, ?suggestions: Array[String]) -> void
7
+
8
+ def with: (?warning: String, ?suggestions: Array[String]) -> Feedback
7
9
  end
8
10
  end
@@ -0,0 +1,36 @@
1
+ module Zxcvbn
2
+ module Guesses
3
+ MIN_GUESSES_BEFORE_GROWING_SEQUENCE: Integer
4
+ MIN_SUBMATCH_GUESSES_SINGLE_CHAR: Integer
5
+ MIN_SUBMATCH_GUESSES_MULTI_CHAR: Integer
6
+ BRUTEFORCE_CARDINALITY: Integer
7
+ MIN_YEAR_SPACE: Integer
8
+
9
+ START_UPPER: Regexp
10
+ END_UPPER: Regexp
11
+ ALL_UPPER: Regexp
12
+ ALL_LOWER: Regexp
13
+
14
+ attr_reader reference_year: Integer
15
+
16
+ def estimate_guesses: (MatchBuilder match, String password) -> Numeric
17
+
18
+ def bruteforce_guesses: (MatchBuilder match) -> Numeric
19
+
20
+ def sequence_guesses: (MatchBuilder match) -> Numeric
21
+
22
+ def digits_guesses: (MatchBuilder match) -> Integer
23
+
24
+ def year_guesses: (MatchBuilder match) -> Integer
25
+
26
+ def date_guesses: (MatchBuilder match) -> Numeric
27
+
28
+ def spatial_guesses: (MatchBuilder match) -> Numeric
29
+
30
+ def dictionary_guesses: (MatchBuilder match) -> Numeric
31
+
32
+ def uppercase_variations: (MatchBuilder match) -> Integer
33
+
34
+ def l33t_variations: (MatchBuilder match) -> Integer
35
+ end
36
+ end
data/sig/zxcvbn/match.rbs CHANGED
@@ -1,38 +1,40 @@
1
1
  module Zxcvbn
2
- class Match
3
- attr_accessor pattern: String?
4
- attr_accessor i: Integer?
5
- attr_accessor j: Integer?
6
- attr_accessor token: String?
7
- attr_accessor matched_word: String?
8
- attr_accessor rank: Integer?
9
- attr_accessor dictionary_name: String?
10
- attr_accessor reversed: bool?
11
- attr_accessor l33t: bool?
12
- attr_accessor sub: Hash[String, String]?
13
- attr_accessor sub_display: String?
14
- attr_accessor l: Integer?
15
- attr_accessor entropy: Numeric?
16
- attr_accessor base_entropy: Numeric?
17
- attr_accessor uppercase_entropy: Numeric?
18
- attr_accessor l33t_entropy: Numeric?
19
- attr_accessor repeated_char: String?
20
- attr_accessor sequence_name: String?
21
- attr_accessor sequence_space: Integer?
22
- attr_accessor ascending: bool?
23
- attr_accessor graph: String?
24
- attr_accessor turns: Integer?
25
- attr_accessor shifted_count: Integer?
26
- attr_accessor shiffted_count: Integer?
27
- attr_accessor year: Integer?
28
- attr_accessor month: Integer?
29
- attr_accessor day: Integer?
30
- attr_accessor separator: String?
31
- attr_accessor cardinality: Integer?
32
- attr_accessor offset: Integer?
2
+ class Match < Data
3
+ attr_reader pattern: String?
4
+ attr_reader i: Integer?
5
+ attr_reader j: Integer?
6
+ attr_reader token: String?
7
+ attr_reader matched_word: String?
8
+ attr_reader rank: Integer?
9
+ attr_reader dictionary_name: String?
10
+ attr_reader reversed: bool?
11
+ attr_reader l33t: bool?
12
+ attr_reader sub: Hash[String, String]?
13
+ attr_reader sub_display: String?
14
+ attr_reader guesses: Numeric?
15
+ attr_reader guesses_log10: Float?
16
+ attr_reader base_guesses: Numeric?
17
+ attr_reader uppercase_variations: Numeric?
18
+ attr_reader l33t_variations: Numeric?
19
+ attr_reader base_token: String?
20
+ attr_reader repeat_count: Integer?
21
+ attr_reader sequence_name: String?
22
+ attr_reader sequence_space: Integer?
23
+ attr_reader ascending: bool?
24
+ attr_reader graph: String?
25
+ attr_reader turns: Integer?
26
+ attr_reader shifted_count: Integer?
27
+ attr_reader year: Integer?
28
+ attr_reader month: Integer?
29
+ attr_reader day: Integer?
30
+ attr_reader separator: String?
33
31
 
34
- def initialize: (**untyped attributes) -> void
32
+ def initialize: (?pattern: String?, ?i: Integer?, ?j: Integer?, ?token: String?, ?matched_word: String?, ?rank: Integer?, ?dictionary_name: String?, ?reversed: bool?, ?l33t: bool?, ?sub: Hash[String, String]?, ?sub_display: String?, ?guesses: Numeric?, ?guesses_log10: Float?, ?base_guesses: Numeric?, ?uppercase_variations: Numeric?, ?l33t_variations: Numeric?, ?base_token: String?, ?repeat_count: Integer?, ?sequence_name: String?, ?sequence_space: Integer?, ?ascending: bool?, ?graph: String?, ?turns: Integer?, ?shifted_count: Integer?, ?year: Integer?, ?month: Integer?, ?day: Integer?, ?separator: String?) -> void
35
33
 
36
- def to_hash: () -> Hash[String, untyped]
34
+ def with: (**untyped) -> Match
35
+
36
+ def inspect: () -> String
37
+
38
+ def pretty_print: (untyped pp) -> void
37
39
  end
38
40
  end
@@ -0,0 +1,36 @@
1
+ module Zxcvbn
2
+ class MatchBuilder
3
+ attr_accessor pattern: String?
4
+ attr_accessor i: Integer?
5
+ attr_accessor j: Integer?
6
+ attr_accessor token: String?
7
+ attr_accessor matched_word: String?
8
+ attr_accessor rank: Integer?
9
+ attr_accessor dictionary_name: String?
10
+ attr_accessor reversed: bool?
11
+ attr_accessor l33t: bool?
12
+ attr_accessor sub: Hash[String, String]?
13
+ attr_accessor sub_display: String?
14
+ attr_accessor guesses: Numeric?
15
+ attr_accessor guesses_log10: Float?
16
+ attr_accessor base_guesses: Numeric?
17
+ attr_accessor uppercase_variations: Numeric?
18
+ attr_accessor l33t_variations: Numeric?
19
+ attr_accessor base_token: String?
20
+ attr_accessor repeat_count: Integer?
21
+ attr_accessor sequence_name: String?
22
+ attr_accessor sequence_space: Integer?
23
+ attr_accessor ascending: bool?
24
+ attr_accessor graph: String?
25
+ attr_accessor turns: Integer?
26
+ attr_accessor shifted_count: Integer?
27
+ attr_accessor year: Integer?
28
+ attr_accessor month: Integer?
29
+ attr_accessor day: Integer?
30
+ attr_accessor separator: String?
31
+
32
+ def initialize: (?pattern: String?, ?i: Integer?, ?j: Integer?, ?token: String?, ?matched_word: String?, ?rank: Integer?, ?dictionary_name: String?, ?reversed: bool?, ?l33t: bool?, ?sub: Hash[String, String]?, ?sub_display: String?, ?guesses: Numeric?, ?guesses_log10: Float?, ?base_guesses: Numeric?, ?uppercase_variations: Numeric?, ?l33t_variations: Numeric?, ?base_token: String?, ?repeat_count: Integer?, ?sequence_name: String?, ?sequence_space: Integer?, ?ascending: bool?, ?graph: String?, ?turns: Integer?, ?shifted_count: Integer?, ?year: Integer?, ?month: Integer?, ?day: Integer?, ?separator: String?) -> void
33
+
34
+ def build: () -> Match
35
+ end
36
+ end
@@ -0,0 +1,23 @@
1
+ module Zxcvbn
2
+ module Matchers
3
+ class Date
4
+ MAYBE_DATE_WITH_SEP: Regexp
5
+ MAYBE_DATE_WITHOUT_SEP: Regexp
6
+ DATE_SPLITS: Hash[Integer, Array[[Integer, Integer]]]
7
+ DATE_MIN_YEAR: Integer
8
+ DATE_MAX_YEAR: Integer
9
+
10
+ def matches: (String password, ?reference_year: Integer) -> Array[MatchBuilder]
11
+
12
+ def match_with_separator: (String password) -> Array[MatchBuilder]
13
+
14
+ def match_without_separator: (String password, ?reference_year: Integer) -> Array[MatchBuilder]
15
+
16
+ def map_ints_to_dmy: (Integer int1, Integer int2, Integer int3) -> { year: Integer, month: Integer, day: Integer }?
17
+
18
+ def map_ints_to_dm: (Integer day_val, Integer month_val) -> { day: Integer, month: Integer }?
19
+
20
+ def expand_year: (Integer year) -> Integer
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ module Zxcvbn
2
+ module Matchers
3
+ class Dictionary
4
+ include CaseHelpers
5
+
6
+ @name: String
7
+ @ranked_dictionary: Data::ranked_dictionary
8
+ @trie: Trie?
9
+
10
+ def initialize: (String name, Data::ranked_dictionary ranked_dictionary, ?Trie? trie) -> void
11
+
12
+ def matches: (String password) -> Array[MatchBuilder]
13
+
14
+ private
15
+
16
+ def trie_matches: (String password, String lowercased_password) -> Array[MatchBuilder]
17
+
18
+ def hash_matches: (String password, String lowercased_password) -> Array[MatchBuilder]
19
+
20
+ def build_match: (String matched_word, String token, Integer start_pos, Integer end_pos, Integer rank) -> MatchBuilder
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ module Zxcvbn
2
+ module Matchers
3
+ class Digits
4
+ include RegexHelpers
5
+
6
+ DIGITS_REGEX: Regexp
7
+
8
+ def matches: (String password) -> Array[MatchBuilder]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ module Zxcvbn
2
+ module Matchers
3
+ class L33t
4
+ include CaseHelpers
5
+
6
+ L33T_TABLE: Hash[String, Array[String]]
7
+
8
+ @dictionary_matchers: Array[Dictionary]
9
+
10
+ def initialize: (Array[Dictionary] dictionary_matchers) -> void
11
+
12
+ def matches: (String password) -> Array[MatchBuilder]
13
+
14
+ def translate: (String password, Hash[String, String] sub) -> String
15
+
16
+ def relevent_l33t_subtable: (String password) -> Hash[String, Array[String]]
17
+
18
+ def l33t_subs: (Hash[String, Array[String]] table) -> Array[Hash[String, String]]
19
+
20
+ private
21
+
22
+ def process_match: (MatchBuilder match, String password, Hash[String, String] substitution, Array[MatchBuilder] matches) -> void
23
+
24
+ def find_substitutions: (Array[untyped] subs, Hash[String, Array[String]] table, Array[String] keys) -> Array[untyped]
25
+
26
+ def dedup: (Array[untyped] subs) -> Array[untyped]
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,7 @@
1
+ module Zxcvbn
2
+ module Matchers
3
+ module RegexHelpers
4
+ def re_match_all: (Regexp regex, String password) { (MatchBuilder, MatchData) -> void } -> void
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ module Zxcvbn
2
+ module Matchers
3
+ class Repeat
4
+ GREEDY: Regexp
5
+ LAZY: Regexp
6
+ LAZY_ANCHORED: Regexp
7
+
8
+ def matches: (String password) -> Array[MatchBuilder]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ module Zxcvbn
2
+ module Matchers
3
+ class Sequences
4
+ MAX_DELTA: Integer
5
+ ALL_LOWER: Regexp
6
+ ALL_UPPER: Regexp
7
+ ALL_DIGITS: Regexp
8
+
9
+ def matches: (String password) -> Array[MatchBuilder]
10
+
11
+ private
12
+
13
+ def classify: (String token) -> [String, Integer]
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module Zxcvbn
2
+ module Matchers
3
+ class Spatial
4
+ SHIFTED_RX: Regexp
5
+
6
+ @graphs: Hash[String, Data::adjacency_graph]
7
+
8
+ def initialize: (Hash[String, Data::adjacency_graph] graphs) -> void
9
+
10
+ def matches: (String password) -> Array[MatchBuilder]
11
+
12
+ def matches_for_graph: (Data::adjacency_graph graph, String graph_name, String password) -> Array[MatchBuilder]
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ module Zxcvbn
2
+ module Matchers
3
+ class Year
4
+ include RegexHelpers
5
+
6
+ YEAR_REGEX: Regexp
7
+
8
+ def matches: (String password) -> Array[MatchBuilder]
9
+ end
10
+ end
11
+ end
data/sig/zxcvbn/math.rbs CHANGED
@@ -1,9 +1,5 @@
1
1
  module Zxcvbn
2
2
  module Math
3
- def bruteforce_cardinality: (String password) -> Integer
4
-
5
- def lg: (Numeric n) -> Float
6
-
7
3
  def nCk: (Integer n, Integer k) -> Integer
8
4
 
9
5
  def average_degree_for_graph: (String graph_name) -> Float
@@ -1,15 +1,18 @@
1
1
  module Zxcvbn
2
2
  class Omnimatch
3
3
  @data: Data
4
+ @dictionary_matchers: Array[Matchers::Dictionary]
4
5
  @matchers: Array[untyped]
5
6
 
6
7
  def initialize: (Data data) -> void
7
8
 
8
- def matches: (String password, ?Array[String] user_inputs) -> Array[Match]
9
+ def matches: (String password, ?Array[String] user_inputs, ?reference_year: Integer) -> Array[MatchBuilder]
9
10
 
10
11
  private
11
12
 
12
- def user_input_matchers: (Array[String] user_inputs) -> Array[untyped]
13
+ def user_input_matchers: (Array[untyped] user_inputs) -> Array[untyped]
14
+
15
+ def reverse_dictionary_matches: (String password, ?Array[untyped] user_inputs) -> Array[MatchBuilder]
13
16
 
14
17
  def build_matchers: () -> Array[untyped]
15
18
  end
data/sig/zxcvbn/score.rbs CHANGED
@@ -1,15 +1,26 @@
1
1
  module Zxcvbn
2
- class Score
3
- attr_accessor entropy: Numeric?
4
- attr_accessor crack_time: Numeric?
5
- attr_accessor crack_time_display: String?
6
- attr_accessor score: Integer?
7
- attr_accessor pattern: String?
8
- attr_accessor match_sequence: Array[Match]?
9
- attr_accessor password: String?
10
- attr_accessor calc_time: Float?
11
- attr_accessor feedback: Feedback?
2
+ class Score < ::Data
3
+ def self.new: (
4
+ password: String,
5
+ guesses: Numeric,
6
+ sequence: Array[Match],
7
+ crack_times_seconds: Hash[String, Float],
8
+ crack_times_display: Hash[String, String],
9
+ score: Integer,
10
+ ?calc_time: Float?,
11
+ ?feedback: Feedback?
12
+ ) -> instance
12
13
 
13
- def initialize: (?entropy: Numeric?, ?crack_time: Numeric?, ?crack_time_display: String?, ?score: Integer?, ?match_sequence: Array[Match]?, ?password: String?) -> void
14
+ attr_reader password: String?
15
+ attr_reader guesses: Numeric?
16
+ attr_reader sequence: Array[Match]?
17
+ attr_reader crack_times_seconds: Hash[String, Float]?
18
+ attr_reader crack_times_display: Hash[String, String]?
19
+ attr_reader score: Integer?
20
+ attr_reader calc_time: Float?
21
+ attr_reader feedback: Feedback?
22
+
23
+ def guesses_log10: () -> Float?
24
+ def with: (**untyped) -> instance
14
25
  end
15
26
  end
@@ -1,20 +1,19 @@
1
1
  module Zxcvbn
2
2
  class Scorer
3
- include Entropy
3
+ include Guesses
4
4
  include CrackTime
5
5
 
6
6
  @data: Data
7
+ @omnimatch: Omnimatch
8
+ @reference_year: Integer
9
+ @repeat_cache: Hash[String, Numeric]
7
10
 
8
11
  attr_reader data: Data
9
12
 
10
- def initialize: (Data data) -> void
13
+ def initialize: (Data data, Omnimatch omnimatch, Integer reference_year) -> void
11
14
 
12
- def minimum_entropy_match_sequence: (String password, Array[Match] matches) -> Score
15
+ def most_guessable_match_sequence: (String password, Array[MatchBuilder] matches, ?exclude_additive: bool) -> Score
13
16
 
14
- def score_for: (String password, Array[Match] match_sequence, Array[Float] up_to_k) -> Score
15
-
16
- def pad_with_bruteforce_matches: (Array[Match] match_sequence, String password, Integer bruteforce_cardinality) -> Array[Match]
17
-
18
- def make_bruteforce_match: (String password, Integer i, Integer j, Integer bruteforce_cardinality) -> Match
17
+ def repeat_guesses: (MatchBuilder match) -> Numeric
19
18
  end
20
19
  end
@@ -1,17 +1,15 @@
1
1
  module Zxcvbn
2
2
  class Tester
3
3
  @data: Data
4
+ @omnimatch: Omnimatch
5
+ @max_password_length: Integer
4
6
 
5
- def initialize: () -> void
7
+ def initialize: (data: Data, max_password_length: untyped) -> void
6
8
 
7
- def test: (String? password, ?Array[untyped] user_inputs) -> Score
9
+ attr_reader max_password_length: Integer
8
10
 
9
- def add_word_lists: (Hash[String, Array[untyped]] lists) -> void
11
+ def test: (String? password, ?(Array[untyped] | String)? user_inputs) -> Score
10
12
 
11
13
  def inspect: () -> String
12
-
13
- private
14
-
15
- def sanitize: (Array[untyped] user_inputs) -> Array[String]
16
14
  end
17
15
  end
@@ -0,0 +1,16 @@
1
+ module Zxcvbn
2
+ class TesterBuilder
3
+ DEFAULT_MAX_PASSWORD_LENGTH: Integer
4
+
5
+ @word_lists: Hash[String, Array[untyped]]
6
+ @max_password_length: Integer?
7
+
8
+ def initialize: () -> void
9
+
10
+ def add_word_list: (String name, ?(Array[untyped] | String)? words) -> TesterBuilder
11
+
12
+ def max_password_length: (Integer length) -> TesterBuilder
13
+
14
+ def build: () -> Tester
15
+ end
16
+ end
data/sig/zxcvbn/trie.rbs CHANGED
@@ -4,10 +4,14 @@ module Zxcvbn
4
4
 
5
5
  @root: node
6
6
 
7
+ def self.from_ranked: (Data::ranked_dictionary ranked_dictionary) -> Trie
8
+
7
9
  def initialize: () -> void
8
10
 
9
11
  def insert: (String word, Integer rank) -> void
10
12
 
13
+ def freeze: () -> self
14
+
11
15
  def search_prefixes: (String text, Integer start_pos) -> Array[[String, Integer?, Integer, Integer]]
12
16
  end
13
17
  end
data/sig/zxcvbn.rbs CHANGED
@@ -1,10 +1,12 @@
1
1
  module Zxcvbn
2
- VERSION: String
2
+ class PasswordTooLong < ArgumentError
3
+ end
3
4
 
4
- DATA_PATH: Pathname
5
+ VERSION: String
5
6
 
6
- type word_list = Hash[String, Array[String]]
7
7
  type user_inputs = Array[String]
8
8
 
9
- def self.test: (String? password, ?user_inputs user_inputs, ?word_list word_lists) -> Score
9
+ def self.test: (String? password, ?user_inputs user_inputs) -> Score
10
+
11
+ def self.tester_builder: () -> TesterBuilder
10
12
  end