zxcvbn-ruby 1.3.0 → 1.4.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 +13 -1
- data/lib/zxcvbn/version.rb +1 -1
- data/sig/README.md +65 -0
- data/sig/zxcvbn/crack_time.rbs +13 -0
- data/sig/zxcvbn/data.rbs +31 -0
- data/sig/zxcvbn/dictionary_ranker.rbs +7 -0
- data/sig/zxcvbn/entropy.rbs +33 -0
- data/sig/zxcvbn/feedback.rbs +8 -0
- data/sig/zxcvbn/feedback_giver.rbs +13 -0
- data/sig/zxcvbn/match.rbs +38 -0
- data/sig/zxcvbn/math.rbs +13 -0
- data/sig/zxcvbn/omnimatch.rbs +16 -0
- data/sig/zxcvbn/password_strength.rbs +10 -0
- data/sig/zxcvbn/score.rbs +15 -0
- data/sig/zxcvbn/scorer.rbs +20 -0
- data/sig/zxcvbn/tester.rbs +17 -0
- data/sig/zxcvbn/trie.rbs +13 -0
- data/sig/zxcvbn.rbs +10 -0
- metadata +22 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 43a759e1040848c8da4bea8d1e871eb7d811d5cab0ebf962255990963b796f75
|
|
4
|
+
data.tar.gz: c78d0453bb8c92d1f3b21c37f1493f305a6667f24e6ae85a621841a9396fb584
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 552d40a11c071613eefb14819b4dabbd3abc6a1f2d336e6bf9bfbc873a34640a229b3bedcc0bd77aca6ffe5e43e31fefec74fe94d74f3cdaebd4e7169610ec02
|
|
7
|
+
data.tar.gz: 84c006df22e0224da4a891f8fa923c81b69229f2b99e5d60ba29104473e566c83a36fbcc404defe980d80cfb176964864f00dbdfa02d655e05eaac7753e64360
|
data/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
-
[Unreleased]: https://github.com/envato/zxcvbn-ruby/compare/v1.
|
|
9
|
+
[Unreleased]: https://github.com/envato/zxcvbn-ruby/compare/v1.4.0...HEAD
|
|
10
|
+
|
|
11
|
+
## [1.4.0] - 2026-01-15
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- RBS type signatures for improved type checking and IDE support ([#68])
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
- Minor fixups in gem metadata ([#67]).
|
|
18
|
+
|
|
19
|
+
[1.4.0]: https://github.com/envato/zxcvbn-ruby/compare/v1.3.0...v1.4.0
|
|
20
|
+
[#67]: https://github.com/envato/zxcvbn-ruby/pull/67
|
|
21
|
+
[#68]: https://github.com/envato/zxcvbn-ruby/pull/68
|
|
10
22
|
|
|
11
23
|
## [1.3.0] - 2026-01-02
|
|
12
24
|
|
data/lib/zxcvbn/version.rb
CHANGED
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,13 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
module CrackTime
|
|
3
|
+
SINGLE_GUESS: Float
|
|
4
|
+
NUM_ATTACKERS: Integer
|
|
5
|
+
SECONDS_PER_GUESS: Float
|
|
6
|
+
|
|
7
|
+
def entropy_to_crack_time: (Numeric entropy) -> Float
|
|
8
|
+
|
|
9
|
+
def crack_time_to_score: (Numeric seconds) -> Integer
|
|
10
|
+
|
|
11
|
+
def display_time: (Numeric seconds) -> String
|
|
12
|
+
end
|
|
13
|
+
end
|
data/sig/zxcvbn/data.rbs
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
@ranked_dictionaries: Hash[String, ranked_dictionary]
|
|
8
|
+
@adjacency_graphs: Hash[String, adjacency_graph]
|
|
9
|
+
@dictionary_tries: Hash[String, Trie]
|
|
10
|
+
@graph_stats: graph_stats
|
|
11
|
+
|
|
12
|
+
attr_reader ranked_dictionaries: Hash[String, ranked_dictionary]
|
|
13
|
+
attr_reader adjacency_graphs: Hash[String, adjacency_graph]
|
|
14
|
+
attr_reader dictionary_tries: Hash[String, Trie]
|
|
15
|
+
attr_reader graph_stats: graph_stats
|
|
16
|
+
|
|
17
|
+
def initialize: () -> void
|
|
18
|
+
|
|
19
|
+
def add_word_list: (String name, Array[String] list) -> void
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def read_word_list: (String file) -> Array[String]
|
|
24
|
+
|
|
25
|
+
def build_tries: () -> Hash[String, Trie]
|
|
26
|
+
|
|
27
|
+
def build_trie: (ranked_dictionary ranked_dictionary) -> Trie
|
|
28
|
+
|
|
29
|
+
def compute_graph_stats: () -> graph_stats
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
module Entropy
|
|
3
|
+
include Zxcvbn::Math
|
|
4
|
+
|
|
5
|
+
def calc_entropy: (Match match) -> Float
|
|
6
|
+
|
|
7
|
+
def repeat_entropy: (Match match) -> Float
|
|
8
|
+
|
|
9
|
+
def sequence_entropy: (Match match) -> Float
|
|
10
|
+
|
|
11
|
+
def digits_entropy: (Match match) -> Float
|
|
12
|
+
|
|
13
|
+
def year_entropy: (Match? match) -> Float
|
|
14
|
+
|
|
15
|
+
def date_entropy: (Match match) -> Float
|
|
16
|
+
|
|
17
|
+
def dictionary_entropy: (Match match) -> Float
|
|
18
|
+
|
|
19
|
+
def extra_uppercase_entropy: (Match match) -> Numeric
|
|
20
|
+
|
|
21
|
+
def extra_l33t_entropy: (Match match) -> Numeric
|
|
22
|
+
|
|
23
|
+
def spatial_entropy: (Match match) -> Float
|
|
24
|
+
|
|
25
|
+
NUM_YEARS: Integer
|
|
26
|
+
NUM_MONTHS: Integer
|
|
27
|
+
NUM_DAYS: Integer
|
|
28
|
+
START_UPPER: Regexp
|
|
29
|
+
END_UPPER: Regexp
|
|
30
|
+
ALL_UPPER: Regexp
|
|
31
|
+
ALL_LOWER: Regexp
|
|
32
|
+
end
|
|
33
|
+
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,38 @@
|
|
|
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?
|
|
33
|
+
|
|
34
|
+
def initialize: (**untyped attributes) -> void
|
|
35
|
+
|
|
36
|
+
def to_hash: () -> Hash[String, untyped]
|
|
37
|
+
end
|
|
38
|
+
end
|
data/sig/zxcvbn/math.rbs
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
module Math
|
|
3
|
+
def bruteforce_cardinality: (String password) -> Integer
|
|
4
|
+
|
|
5
|
+
def lg: (Numeric n) -> Float
|
|
6
|
+
|
|
7
|
+
def nCk: (Integer n, Integer k) -> Integer
|
|
8
|
+
|
|
9
|
+
def average_degree_for_graph: (String graph_name) -> Float
|
|
10
|
+
|
|
11
|
+
def starting_positions_for_graph: (String graph_name) -> Integer
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
class Omnimatch
|
|
3
|
+
@data: Data
|
|
4
|
+
@matchers: Array[untyped]
|
|
5
|
+
|
|
6
|
+
def initialize: (Data data) -> void
|
|
7
|
+
|
|
8
|
+
def matches: (String password, ?Array[String] user_inputs) -> Array[Match]
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def user_input_matchers: (Array[String] user_inputs) -> Array[untyped]
|
|
13
|
+
|
|
14
|
+
def build_matchers: () -> Array[untyped]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
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?
|
|
12
|
+
|
|
13
|
+
def initialize: (?entropy: Numeric?, ?crack_time: Numeric?, ?crack_time_display: String?, ?score: Integer?, ?match_sequence: Array[Match]?, ?password: String?) -> void
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
class Scorer
|
|
3
|
+
include Entropy
|
|
4
|
+
include CrackTime
|
|
5
|
+
|
|
6
|
+
@data: Data
|
|
7
|
+
|
|
8
|
+
attr_reader data: Data
|
|
9
|
+
|
|
10
|
+
def initialize: (Data data) -> void
|
|
11
|
+
|
|
12
|
+
def minimum_entropy_match_sequence: (String password, Array[Match] matches) -> Score
|
|
13
|
+
|
|
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
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
class Tester
|
|
3
|
+
@data: Data
|
|
4
|
+
|
|
5
|
+
def initialize: () -> void
|
|
6
|
+
|
|
7
|
+
def test: (String? password, ?Array[untyped] user_inputs) -> Score
|
|
8
|
+
|
|
9
|
+
def add_word_lists: (Hash[String, Array[untyped]] lists) -> void
|
|
10
|
+
|
|
11
|
+
def inspect: () -> String
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def sanitize: (Array[untyped] user_inputs) -> Array[String]
|
|
16
|
+
end
|
|
17
|
+
end
|
data/sig/zxcvbn/trie.rbs
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Zxcvbn
|
|
2
|
+
class Trie
|
|
3
|
+
type node = Hash[untyped, untyped]
|
|
4
|
+
|
|
5
|
+
@root: node
|
|
6
|
+
|
|
7
|
+
def initialize: () -> void
|
|
8
|
+
|
|
9
|
+
def insert: (String word, Integer rank) -> void
|
|
10
|
+
|
|
11
|
+
def search_prefixes: (String text, Integer start_pos) -> Array[[String, Integer?, Integer, Integer]]
|
|
12
|
+
end
|
|
13
|
+
end
|
data/sig/zxcvbn.rbs
ADDED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zxcvbn-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Steve Hodgkiss
|
|
@@ -54,15 +54,32 @@ files:
|
|
|
54
54
|
- lib/zxcvbn/tester.rb
|
|
55
55
|
- lib/zxcvbn/trie.rb
|
|
56
56
|
- lib/zxcvbn/version.rb
|
|
57
|
-
|
|
57
|
+
- sig/README.md
|
|
58
|
+
- sig/zxcvbn.rbs
|
|
59
|
+
- sig/zxcvbn/crack_time.rbs
|
|
60
|
+
- sig/zxcvbn/data.rbs
|
|
61
|
+
- sig/zxcvbn/dictionary_ranker.rbs
|
|
62
|
+
- sig/zxcvbn/entropy.rbs
|
|
63
|
+
- sig/zxcvbn/feedback.rbs
|
|
64
|
+
- sig/zxcvbn/feedback_giver.rbs
|
|
65
|
+
- sig/zxcvbn/match.rbs
|
|
66
|
+
- sig/zxcvbn/math.rbs
|
|
67
|
+
- sig/zxcvbn/omnimatch.rbs
|
|
68
|
+
- sig/zxcvbn/password_strength.rbs
|
|
69
|
+
- sig/zxcvbn/score.rbs
|
|
70
|
+
- sig/zxcvbn/scorer.rbs
|
|
71
|
+
- sig/zxcvbn/tester.rbs
|
|
72
|
+
- sig/zxcvbn/trie.rbs
|
|
73
|
+
homepage: https://github.com/envato/zxcvbn-ruby
|
|
58
74
|
licenses:
|
|
59
75
|
- MIT
|
|
60
76
|
metadata:
|
|
77
|
+
allowed_push_host: https://rubygems.org
|
|
61
78
|
bug_tracker_uri: https://github.com/envato/zxcvbn-ruby/issues
|
|
62
79
|
changelog_uri: https://github.com/envato/zxcvbn-ruby/blob/HEAD/CHANGELOG.md
|
|
63
|
-
documentation_uri: https://
|
|
80
|
+
documentation_uri: https://www.rubydoc.info/gems/zxcvbn-ruby/1.4.0
|
|
64
81
|
homepage_uri: https://github.com/envato/zxcvbn-ruby
|
|
65
|
-
source_code_uri: https://github.com/envato/zxcvbn-ruby
|
|
82
|
+
source_code_uri: https://github.com/envato/zxcvbn-ruby/tree/v1.4.0
|
|
66
83
|
rdoc_options: []
|
|
67
84
|
require_paths:
|
|
68
85
|
- lib
|
|
@@ -77,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
77
94
|
- !ruby/object:Gem::Version
|
|
78
95
|
version: '0'
|
|
79
96
|
requirements: []
|
|
80
|
-
rubygems_version: 4.0.
|
|
97
|
+
rubygems_version: 4.0.4
|
|
81
98
|
specification_version: 4
|
|
82
99
|
summary: ''
|
|
83
100
|
test_files: []
|