Module: Zxcvbn
- Defined in:
- lib/zxcvbn.rb,
lib/zxcvbn/data.rb,
lib/zxcvbn/math.rb,
lib/zxcvbn/trie.rb,
lib/zxcvbn/clock.rb,
lib/zxcvbn/match.rb,
lib/zxcvbn/score.rb,
lib/zxcvbn/scorer.rb,
lib/zxcvbn/tester.rb,
lib/zxcvbn/guesses.rb,
lib/zxcvbn/version.rb,
lib/zxcvbn/feedback.rb,
lib/zxcvbn/omnimatch.rb,
lib/zxcvbn/crack_time.rb,
lib/zxcvbn/match_builder.rb,
lib/zxcvbn/matchers/date.rb,
lib/zxcvbn/matchers/l33t.rb,
lib/zxcvbn/matchers/year.rb,
lib/zxcvbn/feedback_giver.rb,
lib/zxcvbn/tester_builder.rb,
lib/zxcvbn/matchers/digits.rb,
lib/zxcvbn/matchers/repeat.rb,
lib/zxcvbn/matchers/spatial.rb,
lib/zxcvbn/dictionary_ranker.rb,
lib/zxcvbn/matchers/sequences.rb,
lib/zxcvbn/matchers/dictionary.rb,
lib/zxcvbn/matchers/regex_helpers.rb
Overview
Ruby port of zxcvbn.js — realistic password strength estimation.
Analyses a password against dictionary lists, keyboard patterns, dates, sequences, and repeats to produce a Score with guess estimates and human-readable crack-time display strings.
Defined Under Namespace
Modules: Clock, CrackTime, Guesses, Matchers, Math Classes: Data, DictionaryRanker, Feedback, FeedbackGiver, Match, MatchBuilder, Omnimatch, PasswordTooLong, Score, Scorer, Tester, TesterBuilder, Trie
Constant Summary collapse
- VERSION =
'2.0.0'
Instance Attribute Summary collapse
-
#ascending ⇒ Boolean?
readonly
True if the sequence is ascending.
-
#base_guesses ⇒ Numeric?
readonly
Guesses for the base token (repeat matches) or rank before variation multipliers (dictionary matches).
-
#base_token ⇒ String?
readonly
The minimal repeating unit (repeat matches).
-
#calc_time ⇒ Float?
readonly
Time taken to evaluate, in seconds.
-
#crack_times_display ⇒ Hash{String => String}
readonly
Human-readable crack times per scenario.
-
#crack_times_seconds ⇒ Hash{String => Float}
readonly
Crack time in seconds per attack scenario.
-
#day ⇒ Integer?
readonly
Matched day (date matches).
-
#dictionary_name ⇒ String?
readonly
Source dictionary name (dictionary matches).
-
#feedback ⇒ Feedback?
readonly
Human-readable feedback for low-scoring passwords.
-
#graph ⇒ String?
readonly
Keyboard graph name (spatial matches).
-
#guesses ⇒ Numeric
readonly
Estimated number of guesses to crack the password.
-
#guesses_log10 ⇒ Float?
readonly
Log10 of #guesses.
-
#i ⇒ Integer?
readonly
Start index in the password (inclusive).
-
#j ⇒ Integer?
readonly
End index in the password (inclusive).
-
#l33t ⇒ Boolean?
readonly
True when the match required l33t substitution.
-
#l33t_variations ⇒ Numeric?
readonly
L33t substitution variant count (dictionary matches).
-
#matched_word ⇒ String?
readonly
Lowercased dictionary word (dictionary matches).
-
#month ⇒ Integer?
readonly
Matched month (date matches).
-
#password ⇒ String
readonly
The password that was evaluated.
-
#pattern ⇒ String?
readonly
The matcher that produced this match.
-
#rank ⇒ Integer?
readonly
Frequency rank of the matched word (dictionary matches).
-
#repeat_count ⇒ Integer?
readonly
Number of repetitions (repeat matches).
-
#reversed ⇒ Boolean?
readonly
True when matched in the reversed password.
-
#score ⇒ Integer
readonly
0–4 score (0 = very weak, 4 = very strong).
-
#separator ⇒ String?
readonly
Date separator character (date matches).
-
#sequence ⇒ Array<Match>
readonly
The optimal match sequence.
-
#sequence_name ⇒ String?
readonly
Sequence type: “lower”, “upper”, “digits”, or “unicode”.
-
#sequence_space ⇒ Integer?
readonly
Size of the character set for the sequence.
-
#shifted_count ⇒ Integer?
readonly
Number of shifted characters (spatial matches).
-
#sub ⇒ Hash?
readonly
Map of l33t characters to their substituted letters.
-
#sub_display ⇒ String?
readonly
Human-readable substitution summary.
-
#suggestions ⇒ Array<String>
readonly
Ordered list of improvement tips.
-
#token ⇒ String?
readonly
The matched substring.
-
#turns ⇒ Integer?
readonly
Number of direction changes (spatial matches).
-
#uppercase_variations ⇒ Numeric?
readonly
Capitalisation variant count (dictionary matches).
-
#warning ⇒ String
readonly
A single warning message, or empty string.
-
#year ⇒ Integer?
readonly
Matched year (date/year matches).
Class Method Summary collapse
-
.test(password, user_inputs = []) ⇒ Score
Returns a Zxcvbn::Score for the given password.
-
.tester_builder ⇒ TesterBuilder
Returns a new TesterBuilder for constructing a Tester with custom word lists and options.
Instance Attribute Details
#ascending ⇒ Boolean? (readonly)
Returns true if the sequence is ascending.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#base_guesses ⇒ Numeric? (readonly)
Returns guesses for the base token (repeat matches) or rank before variation multipliers (dictionary matches).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#base_token ⇒ String? (readonly)
Returns the minimal repeating unit (repeat matches).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#calc_time ⇒ Float? (readonly)
Returns time taken to evaluate, in seconds.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/zxcvbn/score.rb', line 22 Score = ::Data.define( :password, :guesses, :sequence, :crack_times_seconds, :crack_times_display, :score, :calc_time, :feedback ) do def initialize(calc_time: nil, feedback: nil, **kwargs) super(calc_time:, feedback:, **kwargs) end # @return [String] a human-readable representation omitting nil fields and password def inspect fields = to_h.reject { |k, v| v.nil? || k == :password }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @return [Float, nil] log10 of {#guesses}, or nil if guesses is not set def guesses_log10 ::Math.log10(guesses) if guesses end end |
#crack_times_display ⇒ Hash{String => String} (readonly)
Returns human-readable crack times per scenario.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/zxcvbn/score.rb', line 22 Score = ::Data.define( :password, :guesses, :sequence, :crack_times_seconds, :crack_times_display, :score, :calc_time, :feedback ) do def initialize(calc_time: nil, feedback: nil, **kwargs) super(calc_time:, feedback:, **kwargs) end # @return [String] a human-readable representation omitting nil fields and password def inspect fields = to_h.reject { |k, v| v.nil? || k == :password }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @return [Float, nil] log10 of {#guesses}, or nil if guesses is not set def guesses_log10 ::Math.log10(guesses) if guesses end end |
#crack_times_seconds ⇒ Hash{String => Float} (readonly)
Returns crack time in seconds per attack scenario.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/zxcvbn/score.rb', line 22 Score = ::Data.define( :password, :guesses, :sequence, :crack_times_seconds, :crack_times_display, :score, :calc_time, :feedback ) do def initialize(calc_time: nil, feedback: nil, **kwargs) super(calc_time:, feedback:, **kwargs) end # @return [String] a human-readable representation omitting nil fields and password def inspect fields = to_h.reject { |k, v| v.nil? || k == :password }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @return [Float, nil] log10 of {#guesses}, or nil if guesses is not set def guesses_log10 ::Math.log10(guesses) if guesses end end |
#day ⇒ Integer? (readonly)
Returns matched day (date matches).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#dictionary_name ⇒ String? (readonly)
Returns source dictionary name (dictionary matches).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#feedback ⇒ Feedback? (readonly)
Returns human-readable feedback for low-scoring passwords.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/zxcvbn/score.rb', line 22 Score = ::Data.define( :password, :guesses, :sequence, :crack_times_seconds, :crack_times_display, :score, :calc_time, :feedback ) do def initialize(calc_time: nil, feedback: nil, **kwargs) super(calc_time:, feedback:, **kwargs) end # @return [String] a human-readable representation omitting nil fields and password def inspect fields = to_h.reject { |k, v| v.nil? || k == :password }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @return [Float, nil] log10 of {#guesses}, or nil if guesses is not set def guesses_log10 ::Math.log10(guesses) if guesses end end |
#graph ⇒ String? (readonly)
Returns keyboard graph name (spatial matches).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#guesses ⇒ Numeric (readonly)
Returns estimated number of guesses to crack the password.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#guesses_log10 ⇒ Float? (readonly)
Returns log10 of #guesses.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#i ⇒ Integer? (readonly)
Returns start index in the password (inclusive).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#j ⇒ Integer? (readonly)
Returns end index in the password (inclusive).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#l33t ⇒ Boolean? (readonly)
Returns true when the match required l33t substitution.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#l33t_variations ⇒ Numeric? (readonly)
Returns l33t substitution variant count (dictionary matches).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#matched_word ⇒ String? (readonly)
Returns lowercased dictionary word (dictionary matches).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#month ⇒ Integer? (readonly)
Returns matched month (date matches).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#password ⇒ String (readonly)
Returns the password that was evaluated.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/zxcvbn/score.rb', line 22 Score = ::Data.define( :password, :guesses, :sequence, :crack_times_seconds, :crack_times_display, :score, :calc_time, :feedback ) do def initialize(calc_time: nil, feedback: nil, **kwargs) super(calc_time:, feedback:, **kwargs) end # @return [String] a human-readable representation omitting nil fields and password def inspect fields = to_h.reject { |k, v| v.nil? || k == :password }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @return [Float, nil] log10 of {#guesses}, or nil if guesses is not set def guesses_log10 ::Math.log10(guesses) if guesses end end |
#pattern ⇒ String? (readonly)
Returns the matcher that produced this match.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#rank ⇒ Integer? (readonly)
Returns frequency rank of the matched word (dictionary matches).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#repeat_count ⇒ Integer? (readonly)
Returns number of repetitions (repeat matches).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#reversed ⇒ Boolean? (readonly)
Returns true when matched in the reversed password.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#score ⇒ Integer (readonly)
Returns 0–4 score (0 = very weak, 4 = very strong).
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/zxcvbn/score.rb', line 22 Score = ::Data.define( :password, :guesses, :sequence, :crack_times_seconds, :crack_times_display, :score, :calc_time, :feedback ) do def initialize(calc_time: nil, feedback: nil, **kwargs) super(calc_time:, feedback:, **kwargs) end # @return [String] a human-readable representation omitting nil fields and password def inspect fields = to_h.reject { |k, v| v.nil? || k == :password }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @return [Float, nil] log10 of {#guesses}, or nil if guesses is not set def guesses_log10 ::Math.log10(guesses) if guesses end end |
#separator ⇒ String? (readonly)
Returns date separator character (date matches).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#sequence ⇒ Array<Match> (readonly)
Returns the optimal match sequence.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/zxcvbn/score.rb', line 22 Score = ::Data.define( :password, :guesses, :sequence, :crack_times_seconds, :crack_times_display, :score, :calc_time, :feedback ) do def initialize(calc_time: nil, feedback: nil, **kwargs) super(calc_time:, feedback:, **kwargs) end # @return [String] a human-readable representation omitting nil fields and password def inspect fields = to_h.reject { |k, v| v.nil? || k == :password }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @return [Float, nil] log10 of {#guesses}, or nil if guesses is not set def guesses_log10 ::Math.log10(guesses) if guesses end end |
#sequence_name ⇒ String? (readonly)
Returns sequence type: “lower”, “upper”, “digits”, or “unicode”.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#sequence_space ⇒ Integer? (readonly)
Returns size of the character set for the sequence.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#shifted_count ⇒ Integer? (readonly)
Returns number of shifted characters (spatial matches).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#sub ⇒ Hash? (readonly)
Returns map of l33t characters to their substituted letters.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#sub_display ⇒ String? (readonly)
Returns human-readable substitution summary.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#suggestions ⇒ Array<String> (readonly)
Returns ordered list of improvement tips.
10 11 12 13 14 15 16 |
# File 'lib/zxcvbn/feedback.rb', line 10 Feedback = ::Data.define(:warning, :suggestions) do # @param warning [String] warning message (default: empty string) # @param suggestions [Array<String>] improvement tips (default: []) def initialize(warning: nil, suggestions: []) super(warning: warning || '', suggestions: suggestions.freeze) end end |
#token ⇒ String? (readonly)
Returns the matched substring.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#turns ⇒ Integer? (readonly)
Returns number of direction changes (spatial matches).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#uppercase_variations ⇒ Numeric? (readonly)
Returns capitalisation variant count (dictionary matches).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
#warning ⇒ String (readonly)
Returns a single warning message, or empty string.
10 11 12 13 14 15 16 |
# File 'lib/zxcvbn/feedback.rb', line 10 Feedback = ::Data.define(:warning, :suggestions) do # @param warning [String] warning message (default: empty string) # @param suggestions [Array<String>] improvement tips (default: []) def initialize(warning: nil, suggestions: []) super(warning: warning || '', suggestions: suggestions.freeze) end end |
#year ⇒ Integer? (readonly)
Returns matched year (date/year matches).
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/zxcvbn/match.rb', line 66 Match = ::Data.define( :pattern, :i, :j, :token, :matched_word, :rank, :dictionary_name, :reversed, :l33t, :sub, :sub_display, :guesses, :guesses_log10, :base_guesses, :uppercase_variations, :l33t_variations, :base_token, :repeat_count, :sequence_name, :sequence_space, :ascending, :graph, :turns, :shifted_count, :year, :month, :day, :separator ) do def initialize( pattern: nil, i: nil, j: nil, token: nil, matched_word: nil, rank: nil, dictionary_name: nil, reversed: nil, l33t: nil, sub: nil, sub_display: nil, guesses: nil, guesses_log10: nil, base_guesses: nil, uppercase_variations: nil, l33t_variations: nil, base_token: nil, repeat_count: nil, sequence_name: nil, sequence_space: nil, ascending: nil, graph: nil, turns: nil, shifted_count: nil, year: nil, month: nil, day: nil, separator: nil ) super end # @return [String] a human-readable representation omitting nil fields and token def inspect fields = to_h.reject { |k, v| v.nil? || k == :token }.map { |k, v| "#{k}=#{v.inspect}" }.join(', ') "#<data #{self.class} #{fields}>" end # @param pp [PP] the pretty-printer instance # @return [void] def pretty_print(pp) fields = to_h.reject { |_, v| v.nil? } pp.group(1, "#<data #{self.class}", '>') do fields.each_with_index do |(k, v), i| pp.text(',') if i.positive? pp.breakable ' ' pp.text("#{k}=") v.pretty_print(pp) end end end end |
Class Method Details
.test(password, user_inputs = []) ⇒ Score
Returns a Zxcvbn::Score for the given password.
Reuses a shared Tester instance across calls. For custom word lists or options, use tester_builder to build a dedicated Tester.
Raises PasswordTooLong (a subclass of ArgumentError) if the password exceeds the configured limit (default: 256 characters). Override process-wide via the ZXCVBN_MAX_PASSWORD_LENGTH environment variable; for per-call limits, use tester_builder with Zxcvbn::TesterBuilder#max_password_length.
Example:
Zxcvbn.test("password").score #=> 0
37 38 39 |
# File 'lib/zxcvbn.rb', line 37 def test(password, user_inputs = []) default_tester.test(password, user_inputs) end |
.tester_builder ⇒ TesterBuilder
Returns a new TesterBuilder for constructing a Tester with custom word lists and options.
Example:
tester = Zxcvbn
.tester_builder
.add_word_list('company', %w[acme corp])
.max_password_length(75)
.build
53 54 55 |
# File 'lib/zxcvbn.rb', line 53 def tester_builder TesterBuilder.new end |