Add types for zxcvbn (#8089)

This commit is contained in:
Sebastian Rittau
2022-06-21 13:34:48 +02:00
committed by GitHub
parent 7ee3b5672c
commit 678c231e5b
8 changed files with 202 additions and 0 deletions

View File

@@ -0,0 +1 @@
version = "4.4.*"

View File

@@ -0,0 +1,18 @@
import datetime
from collections.abc import Iterable
from decimal import Decimal
from typing_extensions import TypedDict
from .feedback import _Feedback
from .matching import _Match
from .time_estimates import _TimeEstimate
class _Result(_TimeEstimate, TypedDict):
password: str
guesses: Decimal
guesses_log10: float
sequence: list[_Match]
calc_time: datetime.timedelta
feedback: _Feedback
def zxcvbn(password: str, user_inputs: Iterable[object] | None = ...) -> _Result: ...

View File

@@ -0,0 +1,5 @@
from typing_extensions import TypeAlias
_Graph: TypeAlias = dict[str, list[str | None]]
ADJACENCY_GRAPHS: dict[str, _Graph]

View File

@@ -0,0 +1,12 @@
from collections.abc import Sequence
from typing_extensions import Literal, TypedDict
from .matching import _Match
class _Feedback(TypedDict):
warning: str
suggestions: list[str]
def get_feedback(score: Literal[0, 1, 2, 3, 4], sequence: Sequence[_Match]) -> _Feedback: ...
def get_match_feedback(match: _Match, is_sole_match: bool) -> _Feedback: ...
def get_dictionary_match_feedback(match: _Match, is_sole_match: bool) -> _Feedback: ...

View File

@@ -0,0 +1 @@
FREQUENCY_LISTS: dict[str, list[str]]

View File

@@ -0,0 +1,94 @@
from collections.abc import Iterable, Mapping
from decimal import Decimal
from typing import Any, Pattern
from typing_extensions import Literal, NotRequired, TypedDict
from .adjacency_graphs import _Graph
class _Match(TypedDict):
pattern: Literal["dictionary", "spatial", "repeat", "sequence", "regex", "date"]
token: str
i: int
j: int
guesses: NotRequired[int] # all patterns except 'date'
guesses_log10: NotRequired[float] # all patterns except 'date'
# pattern == 'date'
separator: NotRequired[str]
year: NotRequired[int]
month: NotRequired[int]
day: NotRequired[int]
# pattern == 'dictionary'
matched_word: NotRequired[str]
dictionary_name: NotRequired[str]
l33t: NotRequired[bool]
reversed: NotRequired[bool]
rank: NotRequired[int]
base_guesses: NotRequired[int | Decimal] # Decimal for 'repeat', see below
uppercase_variations: NotRequired[int]
l33t_variations: NotRequired[int]
# pattern == 'spatial'
turns: NotRequired[int]
# pattern == 'repeat'
base_token: NotRequired[str]
# base_guesses: NotRequired[Decimal]
base_matches: NotRequired[list[Any]] # Any = _Match, https://github.com/python/mypy/issues/731
repeat_count: NotRequired[float]
# pattern == 'regex'
regex_name: NotRequired[str]
def build_ranked_dict(ordered_list: Iterable[str]) -> dict[str, int]: ...
RANKED_DICTIONARIES: dict[str, dict[str, int]]
def add_frequency_lists(frequency_lists_: Mapping[str, Iterable[str]]) -> None: ...
GRAPHS: dict[str, dict[str, list[str | None]]]
L33T_TABLE: dict[str, list[str]]
REGEXEN: dict[str, Pattern[str]]
DATE_MAX_YEAR: int
DATE_MIN_YEAR: int
DATE_SPLITS: dict[int, list[list[int]]]
def omnimatch(password: str, _ranked_dictionaries: dict[str, dict[str, int]] = ...) -> list[_Match]: ...
def dictionary_match(password: str, _ranked_dictionaries: dict[str, dict[str, int]] = ...) -> list[_Match]: ...
def reverse_dictionary_match(password: str, _ranked_dictionaries: dict[str, dict[str, int]] = ...) -> list[_Match]: ...
def relevant_l33t_subtable(password: str, table: Mapping[str, Iterable[str]]) -> dict[str, list[str]]: ...
def enumerate_l33t_subs(table: Mapping[str, Iterable[str]]) -> list[dict[str, str]]: ...
def translate(string: str, chr_map: Mapping[str, str]) -> str: ...
def l33t_match(
password: str, _ranked_dictionaries: dict[str, dict[str, int]] = ..., _l33t_table: dict[str, list[str]] = ...
) -> list[_Match]: ...
def repeat_match(password: str, _ranked_dictionaries: dict[str, dict[str, int]] = ...) -> list[_Match]: ...
def spatial_match(
password: str, _graphs: dict[str, _Graph] = ..., _ranked_dictionaries: dict[str, dict[str, int]] = ...
) -> list[_Match]: ...
SHIFTED_RX: Pattern[str]
def spatial_match_helper(password: str, graph: _Graph, graph_name: str) -> list[_Match]: ...
MAX_DELTA: int
def sequence_match(password: str, _ranked_dictionaries: dict[str, dict[str, int]] = ...) -> list[_Match]: ...
def regex_match(
password: str, _regexen: dict[str, Pattern[str]] = ..., _ranked_dictionaries: dict[str, dict[str, int]] = ...
) -> list[_Match]: ...
def date_match(password: str, _ranked_dictionaries: dict[str, dict[str, int]] = ...) -> list[_Match]: ...
class _DM(TypedDict):
month: int
day: int
class _DMY(TypedDict):
year: int
month: int
day: int
def map_ints_to_dmy(ints: tuple[int, int, int]) -> _DMY | None: ...
def map_ints_to_dm(ints: tuple[int, int]) -> _DM | None: ...
def two_to_four_digit_year(year: int) -> int: ...

View File

@@ -0,0 +1,47 @@
from collections.abc import Iterable
from decimal import Decimal
from typing import Pattern
from typing_extensions import TypedDict
from .adjacency_graphs import _Graph
from .matching import _Match
def calc_average_degree(graph: _Graph) -> float: ...
BRUTEFORCE_CARDINALITY: int
MIN_GUESSES_BEFORE_GROWING_SEQUENCE: int
MIN_SUBMATCH_GUESSES_SINGLE_CHAR: int
MIN_SUBMATCH_GUESSES_MULTI_CHAR: int
MIN_YEAR_SPACE: int
REFERENCE_YEAR: int
class _GuessesResult(TypedDict):
password: str
guesses: int
guesses_log10: float
sequence: list[_Match]
def nCk(n: int, k: int) -> float: ...
def most_guessable_match_sequence(password: str, matches: Iterable[_Match], _exclude_additive: bool = ...) -> _GuessesResult: ...
def estimate_guesses(match: _Match, password: str) -> Decimal: ...
def bruteforce_guesses(match: _Match) -> int: ...
def dictionary_guesses(match: _Match) -> int: ...
def repeat_guesses(match: _Match) -> Decimal: ...
def sequence_guesses(match: _Match) -> int: ...
def regex_guesses(match: _Match) -> int | None: ...
def date_guesses(match: _Match) -> int: ...
KEYBOARD_AVERAGE_DEGREE: float
KEYPAD_AVERAGE_DEGREE: float
KEYBOARD_STARTING_POSITIONS: int
KEYPAD_STARTING_POSITIONS: int
def spatial_guesses(match: _Match) -> int: ...
START_UPPER: Pattern[str]
END_UPPER: Pattern[str]
ALL_UPPER: Pattern[str]
ALL_LOWER: Pattern[str]
def uppercase_variations(match: _Match) -> int: ...
def l33t_variations(match: _Match) -> int: ...

View File

@@ -0,0 +1,24 @@
from decimal import Decimal
from typing_extensions import Literal, TypedDict
class _TimeEstimate(TypedDict):
crack_times_seconds: _CrackTimeSeconds
crack_times_display: _CrackTimesDisplay
score: Literal[0, 1, 2, 3, 4]
class _CrackTimeSeconds(TypedDict):
online_throttling_100_per_hour: Decimal
online_no_throttling_10_per_second: Decimal
offline_slow_hashing_1e4_per_second: Decimal
offline_fast_hashing_1e10_per_second: Decimal
class _CrackTimesDisplay(TypedDict):
online_throttling_100_per_hour: str
online_no_throttling_10_per_second: str
offline_slow_hashing_1e4_per_second: str
offline_fast_hashing_1e10_per_second: str
def estimate_attack_times(guesses: Decimal | float) -> _TimeEstimate: ...
def guesses_to_score(guesses: Decimal) -> Literal[0, 1, 2, 3, 4]: ...
def display_time(seconds: float) -> str: ...
def float_to_decimal(f: float) -> Decimal: ...