# @suaveplan/password-strength - zxcvbn-style password strength estimator — pattern-matching + dictionary cracker model per Wheeler 2016. Universal, zero browser/Node/React deps. ## Summary zxcvbn-style password strength estimator — pattern-matching + dictionary cracker model per Wheeler 2016. Universal; zero browser/Node/React deps. Re-implementation of the open-source `dropbox/zxcvbn` algorithm in style: Zod boundaries, OTel histograms + counters, structured `PWSTRENGTH.*` error codes, 100% coverage, multilingual dictionary subpaths, runtime dictionary swap, observable streaming variant, and a hard 200-character DoS guard. ## Documentation tree - [assess](./src/assess/assess.md) — _(no submodules)_ - [assess-reactive](./src/assess/assess-reactive.md) — Debounce + cancel-on-newer-input wrapper around `assess` for UI strength meters that update as the user types. Each new… - [assess](./src/assess/assess.md) — _(no submodules)_ - [dicts](./src/dicts/load-dictionaries.md) — _(no submodules)_ - wikipedia — _(no submodules… - [de](./src/dicts/de/wikipedia.md) — _(no submodules)_ - [wikipedia](./src/dicts/de/wikipedia.md) — _(no submodules)_ - [english-wikipedia](./src/dicts/en/english-wikipedia.md) — Frequency-ranked dictionary of the most common English tokens observed in Wikipedia. The matcher uses this to flag pass… - [names](./src/dicts/en/names.md) — Frequency-ranked dictionaries of common US given names (male and female) and surnames. Names are over-represented in pa… - [passwords](./src/dicts/en/passwords.md) — Frequency-ranked dictionary of the most common passwords observed across public breach corpora (RockYou, HaveIBeenPwned… - [es](./src/dicts/es/wikipedia.md) — _(no submodules)_ - [wikipedia](./src/dicts/es/wikipedia.md) — _(no submodules)_ - [fr](./src/dicts/fr/wikipedia.md) — _(no submodules)_ - [wikipedia](./src/dicts/fr/wikipedia.md) — _(no submodules)_ - [ru](./src/dicts/ru/wikipedia.md) — _(no submodules)_ - [wikipedia](./src/dicts/ru/wikipedia.md) — _(no submodules)_ - [zh-Hans](./src/dicts/zh-Hans/wikipedia.md) — _(no submodules)_ - [wikipedia](./src/dicts/zh-Hans/wikipedia.md) — _(no submodules)_ - [load-dictionaries](./src/dicts/load-dictionaries.md) — _(no submodules)_ - wikipedia — _(no submodules… - [errors](./src/errors/error-codes.md) — _(no submodules)_ - [error-codes](./src/errors/error-codes.md) — _(no submodules)_ - [feedback](./src/feedback/feedback.md) — _(no submodules)_ - [feedback](./src/feedback/feedback.md) — _(no submodules)_ - [graphs](./src/graphs/validate-graph.md) — _(no submodules)_ - azerty — _(no submodules)_… - [azerty](./src/graphs/azerty/azerty.md) — _(no submodules)_ - [azerty](./src/graphs/azerty/azerty.md) — _(no submodules)_ - [dvorak](./src/graphs/dvorak/dvorak.md) — _(no submodules)_ - [dvorak](./src/graphs/dvorak/dvorak.md) — _(no submodules)_ - [qwerty](./src/graphs/qwerty/qwerty.md) — _(no submodules)_ - [qwerty](./src/graphs/qwerty/qwerty.md) — _(no submodules)_ - [validate-graph](./src/graphs/validate-graph.md) — _(no submodules)_ - azerty — _(no submodules)_… - [matchers](./src/matchers/types.md) — _(no submodules)_ - date — _(no submodules)_ _(no submodules)_ - [date](./src/matchers/date/date.md) — _(no submodules)_ - [dictionary](./src/matchers/dictionary/dictionary.md) — _(no submodules)_ - l33t-table — Provides the default character → lette… - [dictionary](./src/matchers/dictionary/dictionary.md) — _(no submodules)_ - l33t-table — Provides the default character → lette… - [l33t-table](./src/matchers/dictionary/l33t-table.md) — Provides the default character → letter substitution table used by the `dictionaryMatch` matcher to recognise l33t-enco… - [keyboard](./src/matchers/keyboard/keyboard.md) — _(no submodules)_ - [keyboard](./src/matchers/keyboard/keyboard.md) — _(no submodules)_ - [regex](./src/matchers/regex/regex.md) — _(no submodules)_ - [regex](./src/matchers/regex/regex.md) — _(no submodules)_ - [repeat](./src/matchers/repeat/repeat.md) — _(no submodules)_ - [repeat](./src/matchers/repeat/repeat.md) — _(no submodules)_ - [sequence](./src/matchers/sequence/sequence.md) — _(no submodules)_ - [sequence](./src/matchers/sequence/sequence.md) — _(no submodules)_ - [types](./src/matchers/types.md) — _(no submodules)_ - date — _(no submodules)_ _(no submodules)_ - [metrics](./src/observability/metrics.md) — _(no submodules)_ - [schemas](./src/schemas/schemas.md) — _(no submodules)_ - [schemas](./src/schemas/schemas.md) — _(no submodules)_ - [crack-times](./src/scoring/crack-times.md) — Maps a `guesses` count to seconds-to-crack under the four canonical attack scenarios from Wheeler 2016 section 5: onlin… - [estimate-guesses](./src/scoring/estimate-guesses.md) — Implements the Wheeler 2016 section 4 closed-form guess estimates per pattern type: dictionary (rank × uppercase × l33t… - [most-guessable-match-sequence](./src/scoring/most-guessable-match-sequence.md) — Picks the lowest-`Π guesses × k!` cover of the password from the union of pattern matches plus implicit bruteforce-char… - [score](./src/scoring/score.md) — Maps a `guesses` count to a coarse integer score per Wheeler 2016 section 5. This score (`0`–`4`) is what most consumer… - [assess-reactive](./src/assess/assess-reactive.md) — Debounce + cancel-on-newer-input wrapper around `assess` for UI strength meters that update as the user types. Each new… - [assess](./src/assess/assess.md) — _(no submodules)_- [dicts](./src/dicts/load-dictionaries.md) — _(no submodules)_- [de](./src/dicts/de/wikipedia.md) — _(no submodules)_- [wikipedia](./src/dicts/de/wikipedia.md) — _(no submodules)_- [english-wikipedia](./src/dicts/en/english-wikipedia.md) — Frequency-ranked dictionary of the most common English tokens observed in Wikipedia. The matcher uses this to flag pass… - [names](./src/dicts/en/names.md) — Frequency-ranked dictionaries of common US given names (male and female) and surnames. Names are over-represented in pa… - [passwords](./src/dicts/en/passwords.md) — Frequency-ranked dictionary of the most common passwords observed across public breach corpora (RockYou, HaveIBeenPwned… - [es](./src/dicts/es/wikipedia.md) — _(no submodules)_- [wikipedia](./src/dicts/es/wikipedia.md) — _(no submodules)_- [fr](./src/dicts/fr/wikipedia.md) — _(no submodules)_- [wikipedia](./src/dicts/fr/wikipedia.md) — _(no submodules)_- [ru](./src/dicts/ru/wikipedia.md) — _(no submodules)_- [wikipedia](./src/dicts/ru/wikipedia.md) — _(no submodules)_- [zh-Hans](./src/dicts/zh-Hans/wikipedia.md) — _(no submodules)_- [wikipedia](./src/dicts/zh-Hans/wikipedia.md) — _(no submodules)_- [load-dictionaries](./src/dicts/load-dictionaries.md) — _(no submodules)_- [errors](./src/errors/error-codes.md) — _(no submodules)_- [error-codes](./src/errors/error-codes.md) — _(no submodules)_- [feedback](./src/feedback/feedback.md) — _(no submodules)_- [feedback](./src/feedback/feedback.md) — _(no submodules)_- [graphs](./src/graphs/validate-graph.md) — _(no submodules)_- [azerty](./src/graphs/azerty/azerty.md) — _(no submodules)_- [azerty](./src/graphs/azerty/azerty.md) — _(no submodules)_- [dvorak](./src/graphs/dvorak/dvorak.md) — _(no submodules)_- [dvorak](./src/graphs/dvorak/dvorak.md) — _(no submodules)_- [qwerty](./src/graphs/qwerty/qwerty.md) — _(no submodules)_- [qwerty](./src/graphs/qwerty/qwerty.md) — _(no submodules)_- [validate-graph](./src/graphs/validate-graph.md) — _(no submodules)_- [matchers](./src/matchers/types.md) — _(no submodules)_- [date](./src/matchers/date/date.md) — _(no submodules)_- [date](./src/matchers/date/date.md) — _(no submodules)_- [dictionary](./src/matchers/dictionary/dictionary.md) — _(no submodules)_- l33t-table — Provides the default character → lette… - [dictionary](./src/matchers/dictionary/dictionary.md) — _(no submodules)_- l33t-table — Provides the default character → lette… - [l33t-table](./src/matchers/dictionary/l33t-table.md) — Provides the default character → letter substitution table used by the `dictionaryMatch` matcher to recognise l33t-enco… - [keyboard](./src/matchers/keyboard/keyboard.md) — _(no submodules)_- [keyboard](./src/matchers/keyboard/keyboard.md) — _(no submodules)_- [regex](./src/matchers/regex/regex.md) — _(no submodules)_- [regex](./src/matchers/regex/regex.md) — _(no submodules)_- [repeat](./src/matchers/repeat/repeat.md) — _(no submodules)_- [repeat](./src/matchers/repeat/repeat.md) — _(no submodules)_- [sequence](./src/matchers/sequence/sequence.md) — _(no submodules)_- [sequence](./src/matchers/sequence/sequence.md) — _(no submodules)_- [types](./src/matchers/types.md) — _(no submodules)_- [observability](./src/observability/metrics.md) — _(no submodules)_- [metrics](./src/observability/metrics.md) — _(no submodules)_- [schemas](./src/schemas/schemas.md) — _(no submodules)_- [schemas](./src/schemas/schemas.md) — _(no submodules)_- [crack-times](./src/scoring/crack-times.md) — Maps a `guesses` count to seconds-to-crack under the four canonical attack scenarios from Wheeler 2016 section 5: onlin… - [estimate-guesses](./src/scoring/estimate-guesses.md) — Implements the Wheeler 2016 section 4 closed-form guess estimates per pattern type: dictionary (rank × uppercase × l33t… - [most-guessable-match-sequence](./src/scoring/most-guessable-match-sequence.md) — Picks the lowest-`Π guesses × k!` cover of the password from the union of pattern matches plus implicit bruteforce-char… - [score](./src/scoring/score.md) — Maps a `guesses` count to a coarse integer score per Wheeler 2016 section 5. This score (`0`–`4`) is what most consumer… - [assess-reactive](./src/assess/assess-reactive.md) — Debounce + cancel-on-newer-input wrapper around `assess` for UI strength meters that update as the user types. Each new… - [assess](./src/assess/assess.md) — _(no submodules)_- [dicts](./src/dicts/load-dictionaries.md) — _(no submodules)_- wikipedia — _(no submodules)_- [wikipedia](./src/dicts/de/wikipedia.md) — _(no submodules)_- [english-wikipedia](./src/dicts/en/english-wikipedia.md) — Frequency-ranked dictionary of the most common English tokens observed in Wikipedia. The matcher uses this to flag pass… - [names](./src/dicts/en/names.md) — Frequency-ranked dictionaries of common US given names (male and female) and surnames. Names are over-represented in pa… - [passwords](./src/dicts/en/passwords.md) — Frequency-ranked dictionary of the most common passwords observed across public breach corpora (RockYou, HaveIBeenPwned… - [es](./src/dicts/es/wikipedia.md) — _(no submodules)_- [wikipedia](./src/dicts/es/wikipedia.md) — _(no submodules)_- [fr](./src/dicts/fr/wikipedia.md) — _(no submodules)_- [wikipedia](./src/dicts/fr/wikipedia.md) — _(no submodules)_- [ru](./src/dicts/ru/wikipedia.md) — _(no submodules)_- [wikipedia](./src/dicts/ru/wikipedia.md) — _(no submodules)_- [zh-Hans](./src/dicts/zh-Hans/wikipedia.md) — _(no submodules)_- [wikipedia](./src/dicts/zh-Hans/wikipedia.md) — _(no submodules)_- [load-dictionaries](./src/dicts/load-dictionaries.md) — _(no submodules)_- wikipedia — _(no submodules)_- [error-codes](./src/errors/error-codes.md) — _(no submodules)_- [feedback](./src/feedback/feedback.md) — _(no submodules)_- [feedback](./src/feedback/feedback.md) — _(no submodules)_- [graphs](./src/graphs/validate-graph.md) — _(no submodules)_- azerty — _(no submodules)_- [azerty](./src/graphs/azerty/azerty.md) — _(no submodules)_- [dvorak](./src/graphs/dvorak/dvorak.md) — _(no submodules)_- [dvorak](./src/graphs/dvorak/dvorak.md) — _(no submodules)_- [qwerty](./src/graphs/qwerty/qwerty.md) — _(no submodules)_- [qwerty](./src/graphs/qwerty/qwerty.md) — _(no submodules)_- [validate-graph](./src/graphs/validate-graph.md) — _(no submodules)_- azerty — _(no submodules)_- date — _(no submodules)_- [date](./src/matchers/date/date.md) — _(no submodules)_- [dictionary](./src/matchers/dictionary/dictionary.md) — _(no submodules)_- l33t-table — Provides the default character → lette… - [dictionary](./src/matchers/dictionary/dictionary.md) — _(no submodules)_- l33t-table — Provides the default character → lette… - [l33t-table](./src/matchers/dictionary/l33t-table.md) — Provides the default character → letter substitution table used by the `dictionaryMatch` matcher to recognise l33t-enco… - [keyboard](./src/matchers/keyboard/keyboard.md) — _(no submodules)_- [keyboard](./src/matchers/keyboard/keyboard.md) — _(no submodules)_- [regex](./src/matchers/regex/regex.md) — _(no submodules)_- [regex](./src/matchers/regex/regex.md) — _(no submodules)_- [repeat](./src/matchers/repeat/repeat.md) — _(no submodules)_- [repeat](./src/matchers/repeat/repeat.md) — _(no submodules)_- [sequence](./src/matchers/sequence/sequence.md) — _(no submodules)_- [sequence](./src/matchers/sequence/sequence.md) — _(no submodules)_- [types](./src/matchers/types.md) — _(no submodules)_- date — _(no submodules)_- [metrics](./src/observability/metrics.md) — _(no submodules)_- [schemas](./src/schemas/schemas.md) — _(no submodules)_- [schemas](./src/schemas/schemas.md) — _(no submodules)_- [crack-times](./src/scoring/crack-times.md) — Maps a `guesses` count to seconds-to-crack under the four canonical attack scenarios from Wheeler 2016 section 5: onlin… - [estimate-guesses](./src/scoring/estimate-guesses.md) — Implements the Wheeler 2016 section 4 closed-form guess estimates per pattern type: dictionary (rank × uppercase × l33t… - [most-guessable-match-sequence](./src/scoring/most-guessable-match-sequence.md) — Picks the lowest-`Π guesses × k!` cover of the password from the union of pattern matches plus implicit bruteforce-char… - [score](./src/scoring/score.md) — Maps a `guesses` count to a coarse integer score per Wheeler 2016 section 5. This score (`0`–`4`) is what most consumer… - [assess-reactive](./src/assess/assess-reactive.md) — Debounce + cancel-on-newer-input wrapper around `assess` for UI strength meters that update as the user types. Each new… - [assess](./src/assess/assess.md) — _(no submodules)_- [dicts](./src/dicts/load-dictionaries.md) — _(no submodules)_- wikipedia — _(no submodule… - [de](./src/dicts/de/wikipedia.md) — _(no submodules)_- [wikipedia](./src/dicts/de/wikipedia.md) — _(no submodules)_- [english-wikipedia](./src/dicts/en/english-wikipedia.md) — Frequency-ranked dictionary of the most common English tokens observed in Wikipedia. The matcher uses this to flag pass… - [names](./src/dicts/en/names.md) — Frequency-ranked dictionaries of common US given names (male and female) and surnames. Names are over-represented in pa… - [passwords](./src/dicts/en/passwords.md) — Frequency-ranked dictionary of the most common passwords observed across public breach corpora (RockYou, HaveIBeenPwned… - [es](./src/dicts/es/wikipedia.md) — _(no submodules)_- [wikipedia](./src/dicts/es/wikipedia.md) — _(no submodules)_- [fr](./src/dicts/fr/wikipedia.md) — _(no submodules)_- [wikipedia](./src/dicts/fr/wikipedia.md) — _(no submodules)_- [ru](./src/dicts/ru/wikipedia.md) — _(no submodules)_- [wikipedia](./src/dicts/ru/wikipedia.md) — _(no submodules)_- [zh-Hans](./src/dicts/zh-Hans/wikipedia.md) — _(no submodules)_- [wikipedia](./src/dicts/zh-Hans/wikipedia.md) — _(no submodules)_- [load-dictionaries](./src/dicts/load-dictionaries.md) — _(no submodules)_- wikipedia — _(no submodule… - [errors](./src/errors/error-codes.md) — _(no submodules)_- [error-codes](./src/errors/error-codes.md) — _(no submodules)_- [feedback](./src/feedback/feedback.md) — _(no submodules)_- [feedback](./src/feedback/feedback.md) — _(no submodules)_- [graphs](./src/graphs/validate-graph.md) — _(no submodules)_- azerty — _(no submodules)_… - [azerty](./src/graphs/azerty/azerty.md) — _(no submodules)_- [azerty](./src/graphs/azerty/azerty.md) — _(no submodules)_- [dvorak](./src/graphs/dvorak/dvorak.md) — _(no submodules)_- [dvorak](./src/graphs/dvorak/dvorak.md) — _(no submodules)_- [qwerty](./src/graphs/qwerty/qwerty.md) — _(no submodules)_- [qwerty](./src/graphs/qwerty/qwerty.md) — _(no submodules)_- [validate-graph](./src/graphs/validate-graph.md) — _(no submodules)_- azerty — _(no submodules)_… - [matchers](./src/matchers/types.md) — _(no submodules)_- date — _(no submodules)_ <… - [date](./src/matchers/date/date.md) — _(no submodules)_- [date](./src/matchers/date/date.md) — _(no submodules)_- [dictionary](./src/matchers/dictionary/dictionary.md) — _(no submodules)_- l33t-table — Provides the default character → lette… - [dictionary](./src/matchers/dictionary/dictionary.md) — _(no submodules)_- l33t-table — Provides the default character → lette… - [l33t-table](./src/matchers/dictionary/l33t-table.md) — Provides the default character → letter substitution table used by the `dictionaryMatch` matcher to recognise l33t-enco… - [keyboard](./src/matchers/keyboard/keyboard.md) — _(no submodules)_- [keyboard](./src/matchers/keyboard/keyboard.md) — _(no submodules)_- [regex](./src/matchers/regex/regex.md) — _(no submodules)_- [regex](./src/matchers/regex/regex.md) — _(no submodules)_- [repeat](./src/matchers/repeat/repeat.md) — _(no submodules)_- [repeat](./src/matchers/repeat/repeat.md) — _(no submodules)_- [sequence](./src/matchers/sequence/sequence.md) — _(no submodules)_- [sequence](./src/matchers/sequence/sequence.md) — _(no submodules)_- [types](./src/matchers/types.md) — _(no submodules)_- date — _(no submodules)_ <… - [observability](./src/observability/metrics.md) — _(no submodules)_- [metrics](./src/observability/metrics.md) — _(no submodules)_- [schemas](./src/schemas/schemas.md) — _(no submodules)_- [schemas](./src/schemas/schemas.md) — _(no submodules)_- [crack-times](./src/scoring/crack-times.md) — Maps a `guesses` count to seconds-to-crack under the four canonical attack scenarios from Wheeler 2016 section 5: onlin… - [estimate-guesses](./src/scoring/estimate-guesses.md) — Implements the Wheeler 2016 section 4 closed-form guess estimates per pattern type: dictionary (rank × uppercase × l33t… - [most-guessable-match-sequence](./src/scoring/most-guessable-match-sequence.md) — Picks the lowest-`Π guesses × k!` cover of the password from the union of pattern matches plus implicit bruteforce-char… - [score](./src/scoring/score.md) — Maps a `guesses` count to a coarse integer score per Wheeler 2016 section 5. This score (`0`–`4`) is what most consumer… - [assess-reactive](./src/assess/assess-reactive.md) — Debounce + cancel-on-newer-input wrapper around `assess` for UI strength meters that update as the user types. Each new… - [assess](./src/assess/assess.md) — _(no submodules)_- [dicts](./src/dicts/load-dictionaries.md) — _(no submodules)_ - [de](./src/dicts/de/wikipedia.md) — _(no submodules)_ - [wikipedia](./src/dicts/de/wikipedia.md) — _(no submodules)_ - [english-wikipedia](./src/dicts/en/english-wikipedia.md) — Frequency-ranked dictionary of the most common English tokens observed in Wikipedia. The matcher uses this to flag pass… - [names](./src/dicts/en/names.md) — Frequency-ranked dictionaries of common US given names (male and female) and surnames. Names are over-represented in pa… - [passwords](./src/dicts/en/passwords.md) — Frequency-ranked dictionary of the most common passwords observed across public breach corpora (RockYou, HaveIBeenPwned… - [es](./src/dicts/es/wikipedia.md) — _(no submodules)_ - [wikipedia](./src/dicts/es/wikipedia.md) — _(no submodules)_ - [fr](./src/dicts/fr/wikipedia.md) — _(no submodules)_ - [wikipedia](./src/dicts/fr/wikipedia.md) — _(no submodules)_ - [ru](./src/dicts/ru/wikipedia.md) — _(no submodules)_ - [wikipedia](./src/dicts/ru/wikipedia.md) — _(no submodules)_ - [zh-Hans](./src/dicts/zh-Hans/wikipedia.md) — _(no submodules)_ - [wikipedia](./src/dicts/zh-Hans/wikipedia.md) — _(no submodules)_ - [load-dictionaries](./src/dicts/load-dictionaries.md) — _(no submodules)_- [errors](./src/errors/error-codes.md) — _(no submodules)_ - [error-codes](./src/errors/error-codes.md) — _(no submodules)_- [feedback](./src/feedback/feedback.md) — _(no submodules)_ - [feedback](./src/feedback/feedback.md) — _(no submodules)_- [graphs](./src/graphs/validate-graph.md) — _(no submodules)_ - [azerty](./src/graphs/azerty/azerty.md) — _(no submodules)_ - [azerty](./src/graphs/azerty/azerty.md) — _(no submodules)_ - [dvorak](./src/graphs/dvorak/dvorak.md) — _(no submodules)_ - [dvorak](./src/graphs/dvorak/dvorak.md) — _(no submodules)_ - [qwerty](./src/graphs/qwerty/qwerty.md) — _(no submodules)_ - [qwerty](./src/graphs/qwerty/qwerty.md) — _(no submodules)_ - [validate-graph](./src/graphs/validate-graph.md) — _(no submodules)_- [matchers](./src/matchers/types.md) — _(no submodules)_ - [date](./src/matchers/date/date.md) — _(no submodules)_ - [date](./src/matchers/date/date.md) — _(no submodules)_ - [dictionary](./src/matchers/dictionary/dictionary.md) — _(no submodules)_ - [dictionary](./src/matchers/dictionary/dictionary.md) — _(no submodules)_ - [l33t-table](./src/matchers/dictionary/l33t-table.md) — Provides the default character → letter substitution table used by the `dictionaryMatch` matcher to recognise l33t-enco… - [keyboard](./src/matchers/keyboard/keyboard.md) — _(no submodules)_ - [keyboard](./src/matchers/keyboard/keyboard.md) — _(no submodules)_ - [regex](./src/matchers/regex/regex.md) — _(no submodules)_ - [regex](./src/matchers/regex/regex.md) — _(no submodules)_ - [repeat](./src/matchers/repeat/repeat.md) — _(no submodules)_ - [repeat](./src/matchers/repeat/repeat.md) — _(no submodules)_ - [sequence](./src/matchers/sequence/sequence.md) — _(no submodules)_ - [sequence](./src/matchers/sequence/sequence.md) — _(no submodules)_ - [types](./src/matchers/types.md) — _(no submodules)_- [observability](./src/observability/metrics.md) — _(no submodules)_ - [metrics](./src/observability/metrics.md) — _(no submodules)_- [schemas](./src/schemas/schemas.md) — _(no submodules)_ - [schemas](./src/schemas/schemas.md) — _(no submodules)_- [crack-times](./src/scoring/crack-times.md) — Maps a `guesses` count to seconds-to-crack under the four canonical attack scenarios from Wheeler 2016 section 5: onlin… - [estimate-guesses](./src/scoring/estimate-guesses.md) — Implements the Wheeler 2016 section 4 closed-form guess estimates per pattern type: dictionary (rank × uppercase × l33t… - [most-guessable-match-sequence](./src/scoring/most-guessable-match-sequence.md) — Picks the lowest-`Π guesses × k!` cover of the password from the union of pattern matches plus implicit bruteforce-char… - [score](./src/scoring/score.md) — Maps a `guesses` count to a coarse integer score per Wheeler 2016 section 5. This score (`0`–`4`) is what most consumer… ## Install ```bash bun add @suaveplan/password-strength ``` ## Quick Start ```ts import { assess } from "@suaveplan/password-strength"; const result = assess("Password1!"); console.log(result.score); // 0..4 bucket console.log(result.guesses); // closed-form guess count console.log(result.feedback.warning); // English-default UI string console.log(result.crackTimes.offline_fast_hashing_1e10_per_second); ``` ## Modules | Module | Doc | |---|---| | `errors/error-codes` | [`src/errors/error-codes.md`](src/errors/error-codes.md) | | `matchers/dictionary` | [`src/matchers/dictionary/dictionary.md`](src/matchers/dictionary/dictionary.md) | | `matchers/dictionary/l33t-table` | [`src/matchers/dictionary/l33t-table.md`](src/matchers/dictionary/l33t-table.md) | | `matchers/sequence` | [`src/matchers/sequence/sequence.md`](src/matchers/sequence/sequence.md) | | `matchers/repeat` | [`src/matchers/repeat/repeat.md`](src/matchers/repeat/repeat.md) | | `matchers/date` | [`src/matchers/date/date.md`](src/matchers/date/date.md) | | `matchers/keyboard` | [`src/matchers/keyboard/keyboard.md`](src/matchers/keyboard/keyboard.md) | | `matchers/regex` | [`src/matchers/regex/regex.md`](src/matchers/regex/regex.md) | | `graphs/qwerty` | [`src/graphs/qwerty/qwerty.md`](src/graphs/qwerty/qwerty.md) | | `graphs/dvorak` | [`src/graphs/dvorak/dvorak.md`](src/graphs/dvorak/dvorak.md) | | `graphs/azerty` | [`src/graphs/azerty/azerty.md`](src/graphs/azerty/azerty.md) | | `graphs/validate-graph` | [`src/graphs/validate-graph.md`](src/graphs/validate-graph.md) | | `dicts/en/passwords` | [`src/dicts/en/passwords.md`](src/dicts/en/passwords.md) | | `dicts/en/english-wikipedia` | [`src/dicts/en/english-wikipedia.md`](src/dicts/en/english-wikipedia.md) | | `dicts/en/names` | [`src/dicts/en/names.md`](src/dicts/en/names.md) | | `dicts/de/wikipedia` | [`src/dicts/de/wikipedia.md`](src/dicts/de/wikipedia.md) | | `dicts/fr/wikipedia` | [`src/dicts/fr/wikipedia.md`](src/dicts/fr/wikipedia.md) | | `dicts/es/wikipedia` | [`src/dicts/es/wikipedia.md`](src/dicts/es/wikipedia.md) | | `dicts/zh-Hans/wikipedia` | [`src/dicts/zh-Hans/wikipedia.md`](src/dicts/zh-Hans/wikipedia.md) | | `dicts/ru/wikipedia` | [`src/dicts/ru/wikipedia.md`](src/dicts/ru/wikipedia.md) | | `dicts/load-dictionaries` | [`src/dicts/load-dictionaries.md`](src/dicts/load-dictionaries.md) | | `scoring/score` | [`src/scoring/score.md`](src/scoring/score.md) | | `scoring/crack-times` | [`src/scoring/crack-times.md`](src/scoring/crack-times.md) | | `scoring/estimate-guesses` | [`src/scoring/estimate-guesses.md`](src/scoring/estimate-guesses.md) | | `scoring/most-guessable-match-sequence` | [`src/scoring/most-guessable-match-sequence.md`](src/scoring/most-guessable-match-sequence.md) | | `assess/assess` | [`src/assess/assess.md`](src/assess/assess.md) | | `assess/assess-reactive` | [`src/assess/assess-reactive.md`](src/assess/assess-reactive.md) | | `feedback/feedback` | [`src/feedback/feedback.md`](src/feedback/feedback.md) | | `schemas` | [`src/schemas/schemas.md`](src/schemas/schemas.md) | | `observability/metrics` | [`src/observability/metrics.md`](src/observability/metrics.md) | ## Features - Six pattern matchers: dictionary (with l33t + reverse), sequence, repeat, date, keyboard adjacency, regex - DP cover with factorial penalty per Wheeler section 4 - Four crack-time scenarios, site-tunable via `adjustments` - 5-bucket score (`0`–`4`) per Wheeler section 5 - 200-character DoS guard - Streaming variant (`assessReactive`) with debounce + cancel-on-newer - Runtime dictionary swap via `loadDictionaries` - Multilingual dictionary subpaths (`en`, `de`, `fr`, `es`, `zh-Hans`, `ru`) - Keyboard graph subpaths (`qwerty`, `dvorak`, `azerty`) - Zod-validated boundaries at every public entry point - OTel histogram + counters for assess duration, score distribution, error code, and matcher hit count ## Baseline benchmarks Run `bun run src/__benchmarks__/assess.bench.ts` to print baseline numbers locally. Indicative timings on commodity hardware (single fork, no warmup): | Bench | Mean | |---|---| | 8-char password | ~0.5 ms | | 64-char password | ~5 ms | | Dictionary-heavy | ~1 ms | | DP n=100 | ~3 ms | | DP n=199 | ~12 ms | The 200-character DoS guard keeps p99 well under the 5 ms `it()` default.