zxcvbn-ruby 1.3.0 → 2.0.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 +4 -4
- data/CHANGELOG.md +71 -1
- data/README.md +322 -75
- data/data/frequency_lists/english_wikipedia.txt +30000 -0
- data/data/frequency_lists/female_names.txt +11 -114
- data/data/frequency_lists/male_names.txt +3 -24
- data/data/frequency_lists/passwords.txt +29623 -6764
- data/data/frequency_lists/surnames.txt +28 -30611
- data/data/frequency_lists/{english.txt → us_tv_and_film.txt} +147 -13532
- data/lib/zxcvbn/clock.rb +6 -0
- data/lib/zxcvbn/crack_time.rb +52 -18
- data/lib/zxcvbn/data.rb +61 -21
- data/lib/zxcvbn/dictionary_ranker.rb +10 -0
- data/lib/zxcvbn/feedback.rb +11 -6
- data/lib/zxcvbn/feedback_giver.rb +75 -50
- data/lib/zxcvbn/guesses.rb +208 -0
- data/lib/zxcvbn/match.rb +95 -15
- data/lib/zxcvbn/match_builder.rb +15 -0
- data/lib/zxcvbn/matchers/date.rb +171 -106
- data/lib/zxcvbn/matchers/dictionary.rb +15 -8
- data/lib/zxcvbn/matchers/digits.rb +6 -1
- data/lib/zxcvbn/matchers/l33t.rb +30 -34
- data/lib/zxcvbn/matchers/regex_helpers.rb +14 -6
- data/lib/zxcvbn/matchers/repeat.rb +47 -16
- data/lib/zxcvbn/matchers/sequences.rb +58 -48
- data/lib/zxcvbn/matchers/spatial.rb +22 -6
- data/lib/zxcvbn/matchers/year.rb +6 -1
- data/lib/zxcvbn/math.rb +15 -28
- data/lib/zxcvbn/omnimatch.rb +70 -22
- data/lib/zxcvbn/ruby.rb +3 -0
- data/lib/zxcvbn/score.rb +34 -10
- data/lib/zxcvbn/scorer.rb +142 -75
- data/lib/zxcvbn/tester.rb +58 -23
- data/lib/zxcvbn/tester_builder.rb +83 -0
- data/lib/zxcvbn/trie.rb +21 -0
- data/lib/zxcvbn/version.rb +1 -1
- data/lib/zxcvbn.rb +47 -7
- data/sig/README.md +65 -0
- data/sig/zxcvbn/clock.rbs +5 -0
- data/sig/zxcvbn/crack_time.rbs +11 -0
- data/sig/zxcvbn/data.rbs +40 -0
- data/sig/zxcvbn/dictionary_ranker.rbs +7 -0
- data/sig/zxcvbn/feedback.rbs +10 -0
- data/sig/zxcvbn/feedback_giver.rbs +13 -0
- data/sig/zxcvbn/guesses.rbs +36 -0
- data/sig/zxcvbn/match.rbs +40 -0
- data/sig/zxcvbn/match_builder.rbs +36 -0
- data/sig/zxcvbn/matchers/date.rbs +23 -0
- data/sig/zxcvbn/matchers/dictionary.rbs +21 -0
- data/sig/zxcvbn/matchers/digits.rbs +11 -0
- data/sig/zxcvbn/matchers/l33t.rbs +27 -0
- data/sig/zxcvbn/matchers/regex_helpers.rbs +7 -0
- data/sig/zxcvbn/matchers/repeat.rbs +11 -0
- data/sig/zxcvbn/matchers/sequences.rbs +16 -0
- data/sig/zxcvbn/matchers/spatial.rbs +15 -0
- data/sig/zxcvbn/matchers/year.rbs +11 -0
- data/sig/zxcvbn/math.rbs +9 -0
- data/sig/zxcvbn/omnimatch.rbs +19 -0
- data/sig/zxcvbn/score.rbs +26 -0
- data/sig/zxcvbn/scorer.rbs +19 -0
- data/sig/zxcvbn/tester.rbs +15 -0
- data/sig/zxcvbn/tester_builder.rbs +16 -0
- data/sig/zxcvbn/trie.rbs +17 -0
- data/sig/zxcvbn.rbs +12 -0
- metadata +46 -12
- data/lib/zxcvbn/entropy.rb +0 -158
- data/lib/zxcvbn/matchers/new_l33t.rb +0 -118
- data/lib/zxcvbn/password_strength.rb +0 -27
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
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
data/sig/README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# RBS Type Signatures
|
|
2
|
+
|
|
3
|
+
This directory contains [RBS](https://github.com/ruby/rbs) type signatures for the zxcvbn-ruby gem.
|
|
4
|
+
|
|
5
|
+
## What is RBS?
|
|
6
|
+
|
|
7
|
+
RBS is Ruby's type signature language. It provides a way to describe the structure of Ruby programs with:
|
|
8
|
+
- Class and module definitions
|
|
9
|
+
- Method signatures with parameter and return types
|
|
10
|
+
- Instance variables and constants
|
|
11
|
+
- Duck typing and union types
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Validating Type Signatures
|
|
16
|
+
|
|
17
|
+
To validate that the RBS files are syntactically correct:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
bundle exec rake rbs:validate
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Runtime Type Checking
|
|
24
|
+
|
|
25
|
+
To run runtime type checking against the actual Ruby code during tests:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bundle exec rake rbs:test
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This runs the RSpec test suite with RBS type checking enabled, verifying that method calls match their type signatures at runtime. Note: This takes about 2 minutes to run.
|
|
32
|
+
|
|
33
|
+
### Other Useful Commands
|
|
34
|
+
|
|
35
|
+
List all Zxcvbn types:
|
|
36
|
+
```bash
|
|
37
|
+
bundle exec rake rbs:list
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Check syntax of RBS files:
|
|
41
|
+
```bash
|
|
42
|
+
bundle exec rake rbs:parse
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## File Structure
|
|
46
|
+
|
|
47
|
+
The signatures mirror the structure of the `lib/` directory:
|
|
48
|
+
|
|
49
|
+
- `sig/zxcvbn.rbs` - Main Zxcvbn module
|
|
50
|
+
- `sig/zxcvbn/*.rbs` - Core classes (Tester, Score, Match, etc.)
|
|
51
|
+
- `sig/zxcvbn/matchers/*.rbs` - Pattern matcher classes
|
|
52
|
+
|
|
53
|
+
## Adding New Signatures
|
|
54
|
+
|
|
55
|
+
When adding new classes or methods to the codebase, remember to:
|
|
56
|
+
|
|
57
|
+
1. Create or update the corresponding `.rbs` file in the `sig/` directory
|
|
58
|
+
2. Run `bundle exec rake rbs_validate` to ensure the syntax is correct
|
|
59
|
+
3. Keep type signatures in sync with the actual implementation
|
|
60
|
+
|
|
61
|
+
## Resources
|
|
62
|
+
|
|
63
|
+
- [RBS Documentation](https://github.com/ruby/rbs)
|
|
64
|
+
- [RBS Syntax Guide](https://github.com/ruby/rbs/blob/master/docs/syntax.md)
|
|
65
|
+
- [Ruby Signature Collection](https://github.com/ruby/gem_rbs_collection)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
module CrackTime
|
|
3
|
+
ATTACK_SCENARIOS: Hash[String, Float]
|
|
4
|
+
|
|
5
|
+
def estimate_attack_times: (Numeric guesses) -> { crack_times_seconds: Hash[String, Float], crack_times_display: Hash[String, String] }
|
|
6
|
+
|
|
7
|
+
def guesses_to_score: (Numeric guesses) -> Integer
|
|
8
|
+
|
|
9
|
+
def display_time: (Numeric seconds) -> String
|
|
10
|
+
end
|
|
11
|
+
end
|
data/sig/zxcvbn/data.rbs
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
class Data
|
|
3
|
+
type ranked_dictionary = Hash[String, Integer]
|
|
4
|
+
type adjacency_graph = Hash[String, Array[String?]]
|
|
5
|
+
type graph_stats = Hash[String, { average_degree: Float, starting_positions: Integer }]
|
|
6
|
+
|
|
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
|
|
17
|
+
@adjacency_graphs: Hash[String, adjacency_graph]
|
|
18
|
+
@graph_stats: graph_stats
|
|
19
|
+
|
|
20
|
+
attr_reader dictionaries: Dictionaries
|
|
21
|
+
attr_reader adjacency_graphs: Hash[String, adjacency_graph]
|
|
22
|
+
attr_reader graph_stats: graph_stats
|
|
23
|
+
|
|
24
|
+
def ranked_dictionaries: () -> Hash[String, ranked_dictionary]
|
|
25
|
+
|
|
26
|
+
def dictionary_tries: () -> Hash[String, Trie]
|
|
27
|
+
|
|
28
|
+
def initialize: () -> void
|
|
29
|
+
|
|
30
|
+
def add_word_list: (String name, Array[untyped] list) -> void
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def read_word_list: (String file) -> Array[String]
|
|
35
|
+
|
|
36
|
+
def build_tries: (Hash[String, ranked_dictionary] ranked) -> Hash[String, Trie]
|
|
37
|
+
|
|
38
|
+
def compute_graph_stats: () -> graph_stats
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
class Feedback < Data
|
|
3
|
+
attr_reader warning: String
|
|
4
|
+
attr_reader suggestions: Array[String]
|
|
5
|
+
|
|
6
|
+
def initialize: (?warning: String, ?suggestions: Array[String]) -> void
|
|
7
|
+
|
|
8
|
+
def with: (?warning: String, ?suggestions: Array[String]) -> Feedback
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
class FeedbackGiver
|
|
3
|
+
NAME_DICTIONARIES: Array[String]
|
|
4
|
+
DEFAULT_FEEDBACK: Feedback
|
|
5
|
+
EMPTY_FEEDBACK: Feedback
|
|
6
|
+
|
|
7
|
+
def self.get_feedback: (Integer? score, Array[Match] sequence) -> Feedback
|
|
8
|
+
|
|
9
|
+
def self.get_match_feedback: (Match match, bool is_sole_match) -> Feedback?
|
|
10
|
+
|
|
11
|
+
def self.get_dictionary_match_feedback: (Match match, bool is_sole_match) -> Feedback
|
|
12
|
+
end
|
|
13
|
+
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
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Zxcvbn
|
|
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?
|
|
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 with: (**untyped) -> Match
|
|
35
|
+
|
|
36
|
+
def inspect: () -> String
|
|
37
|
+
|
|
38
|
+
def pretty_print: (untyped pp) -> void
|
|
39
|
+
end
|
|
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,21 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
module Matchers
|
|
3
|
+
class Dictionary
|
|
4
|
+
@name: String
|
|
5
|
+
@ranked_dictionary: Data::ranked_dictionary
|
|
6
|
+
@trie: Trie?
|
|
7
|
+
|
|
8
|
+
def initialize: (String name, Data::ranked_dictionary ranked_dictionary, ?Trie? trie) -> void
|
|
9
|
+
|
|
10
|
+
def matches: (String password) -> Array[MatchBuilder]
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def trie_matches: (String password, String lowercased_password) -> Array[MatchBuilder]
|
|
15
|
+
|
|
16
|
+
def hash_matches: (String password, String lowercased_password) -> Array[MatchBuilder]
|
|
17
|
+
|
|
18
|
+
def build_match: (String matched_word, String token, Integer start_pos, Integer end_pos, Integer rank) -> MatchBuilder
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
module Matchers
|
|
3
|
+
class L33t
|
|
4
|
+
L33T_TABLE: Hash[String, Array[String]]
|
|
5
|
+
|
|
6
|
+
@dictionary_matchers: Array[Dictionary]
|
|
7
|
+
|
|
8
|
+
def initialize: (Array[Dictionary] dictionary_matchers) -> void
|
|
9
|
+
|
|
10
|
+
def matches: (String password) -> Array[MatchBuilder]
|
|
11
|
+
|
|
12
|
+
def translate: (String password, Hash[String, String] sub) -> String
|
|
13
|
+
|
|
14
|
+
def relevent_l33t_subtable: (String password) -> Hash[String, Array[String]]
|
|
15
|
+
|
|
16
|
+
def l33t_subs: (Hash[String, Array[String]] table) -> Array[Hash[String, String]]
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def process_match: (MatchBuilder match, String password, Hash[String, String] substitution, Array[MatchBuilder] matches) -> void
|
|
21
|
+
|
|
22
|
+
def find_substitutions: (Array[untyped] subs, Hash[String, Array[String]] table, Array[String] keys) -> Array[untyped]
|
|
23
|
+
|
|
24
|
+
def dedup: (Array[untyped] subs) -> Array[untyped]
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
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
|
data/sig/zxcvbn/math.rbs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
class Omnimatch
|
|
3
|
+
@data: Data
|
|
4
|
+
@dictionary_matchers: Array[Matchers::Dictionary]
|
|
5
|
+
@matchers: Array[untyped]
|
|
6
|
+
|
|
7
|
+
def initialize: (Data data) -> void
|
|
8
|
+
|
|
9
|
+
def matches: (String password, ?Array[String] user_inputs, ?reference_year: Integer) -> Array[MatchBuilder]
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
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]
|
|
16
|
+
|
|
17
|
+
def build_matchers: () -> Array[untyped]
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Zxcvbn
|
|
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
|
|
13
|
+
|
|
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
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
class Scorer
|
|
3
|
+
include Guesses
|
|
4
|
+
include CrackTime
|
|
5
|
+
|
|
6
|
+
@data: Data
|
|
7
|
+
@omnimatch: Omnimatch
|
|
8
|
+
@reference_year: Integer
|
|
9
|
+
@repeat_cache: Hash[String, Numeric]
|
|
10
|
+
|
|
11
|
+
attr_reader data: Data
|
|
12
|
+
|
|
13
|
+
def initialize: (Data data, Omnimatch omnimatch, Integer reference_year) -> void
|
|
14
|
+
|
|
15
|
+
def most_guessable_match_sequence: (String password, Array[MatchBuilder] matches, ?exclude_additive: bool) -> Score
|
|
16
|
+
|
|
17
|
+
def repeat_guesses: (MatchBuilder match) -> Numeric
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
class Tester
|
|
3
|
+
@data: Data
|
|
4
|
+
@omnimatch: Omnimatch
|
|
5
|
+
@max_password_length: Integer
|
|
6
|
+
|
|
7
|
+
def initialize: (data: Data, max_password_length: untyped) -> void
|
|
8
|
+
|
|
9
|
+
attr_reader max_password_length: Integer
|
|
10
|
+
|
|
11
|
+
def test: (String? password, ?(Array[untyped] | String)? user_inputs) -> Score
|
|
12
|
+
|
|
13
|
+
def inspect: () -> String
|
|
14
|
+
end
|
|
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
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
class Trie
|
|
3
|
+
type node = Hash[untyped, untyped]
|
|
4
|
+
|
|
5
|
+
@root: node
|
|
6
|
+
|
|
7
|
+
def self.from_ranked: (Data::ranked_dictionary ranked_dictionary) -> Trie
|
|
8
|
+
|
|
9
|
+
def initialize: () -> void
|
|
10
|
+
|
|
11
|
+
def insert: (String word, Integer rank) -> void
|
|
12
|
+
|
|
13
|
+
def freeze: () -> self
|
|
14
|
+
|
|
15
|
+
def search_prefixes: (String text, Integer start_pos) -> Array[[String, Integer?, Integer, Integer]]
|
|
16
|
+
end
|
|
17
|
+
end
|
data/sig/zxcvbn.rbs
ADDED