
    gp                     :   S r SSKJrJrJrJr  SSKrSSKJr   SSK	J
r
  SSKJrJr  SSKr\R"                  " \5      rSSKrSSKrSSKJr  SSKJrJrJrJr  SS	KJrJrJr  SS
K J!r!  / SQr"\#" SSSSSS9r$S r%S r&S(S jr'\(\)4r*\+\,4r-\+" 5       r.S)S jr/ " S S\05      r1\#" SSSSS9r2 " S S\15      r3S*S jr4S  r5 " S! S"\
5      r6\6" 5       r7S#Rq                  5        H  r9\7Ru                  \9S$\9-  5        M      " S% S&\15      r;S*S' jr<g! \ a	    SSKJ
r
   Nf = f)+z*passlib.pwd -- password generation helpers    )absolute_importdivisionprint_functionunicode_literalsN)defaultdict)MutableMapping)ceillog)exc)PY2irange
itervalues	int_types)rng
getrandstr
to_unicode)memoized_property)genworddefault_charsets	genphrasedefault_wordsets      $   0   <   )unsafeweakfairstrongsecurec                 X    [        U 5      R                  nX"R                  U5      S-   S $ )z2return remaining classes in object's MRO after cls   N)type__mro__index)objclsmros      D/home/matz/Project1/venv/lib/python3.13/site-packages/passlib/pwd.py_superclassesr+   8   s*    
s)

Cyy~a !!    c                 .    [        U 5      n[        [        5      nU  H  nX#==   S-  ss'   M     Uc  UR	                  5       n[        U5      nO[        U5      nU(       d  g[        US5      [        S U 5       5      U-  -
  $ ! [         a    Sn Nf = f)a  
returns 'rate of self-information' --
i.e. average (per-symbol) entropy of the sequence **source**,
where probability of a given symbol occurring is calculated based on
the number of occurrences within the sequence itself.

if all elements of the source are unique, this should equal ``log(len(source), 2)``.

:arg source:
    iterable containing 0+ symbols
    (e.g. list of strings or ints, string of characters, etc).

:returns:
    float bits of entropy
Nr#   r      c              3   >   #    U  H  o[        US 5      -  v   M     g7f)r.   N)logf).0values     r*   	<genexpr>"_self_info_rate.<locals>.<genexpr>_   s     J6%tE1~56s   )len	TypeErrorr   intvaluessumr   r0   )sourcesizecountscharr8   s        r*   _self_info_rater>   >   s     6{ F |6{F# a=3J6JJTQQQ  s   B BBc                 :   U(       a%  [         R                  " U5      " [        U 5      5      $ [        R                  R                  U 5      (       a  [        U S5      $ U R                  S5      u  p#nU(       d  [        SU < 35      e[        R                  " X$5      $ )z
:param asset_path:
    string containing absolute path to file,
    or package-relative path using format
    ``"python.module:relative/file/path"``.

:returns:
    filehandle opened in 'rb' mode
    (unless encoding explicitly specified)
rb:zIasset path must be absolute file path or use 'pkg.name:sub/path' format: )codecs	getreader_open_asset_pathospathisabsopen	partition
ValueErrorpkg_resourcesresource_stream)rF   encodingpackagesepsubpaths        r*   rD   rD   j   s     )*:4*@AA	ww}}TD$ NN3/G'DHK L 	L((::r,   c                 R   [         nSn X;   a  g [        U [        5      (       d!  [	        [        U 5      5      [	        U 5      :X  a  U(       a   UR                  U 5        gg[        5       n[        5       nU  H  nXd;   a  UOUR                  U5        M     [        U5      nSn[	        U5      U:  a  SnSR                  S USU  5       5      n[	        U5      U:  a  US[	        U5      U-
  -  -  n[        S	U< S
U< 35      e! [         a    Sn GNf = f! [         a     gf = f)z
helper for generators --
Throws ValueError if source elements aren't unique.
Error message will display (abbreviated) repr of the duplicates in a string/list
TF      , c              3   J   #    U  H  n[        [        U5      5      v   M     g 7fN)reprstrr1   words     r*   r3   !_ensure_unique.<locals>.<genexpr>   s     B\Tc$i\s   !#Nz, ... plus %d others`z%` cannot contain duplicate elements: )
_ensure_unique_cacher6   
isinstance
_set_typesr5   setaddsortedjoinrJ   )	r:   paramcachehashableseendupselemtruncdup_reprs	            r*   _ensure_uniquerl      s/    !EH?  &*%%S[)9S[)H		&!
  5D5D4,,T2 $<DE
4y5yyBT&5\BBH
4y5*c$i%.?@@ X' ( (9     	s#   D D DD
D&%D&c                      ^  \ rS rSrSrSrSr\rSrSU 4S jjr	\
S 5       r\
S 5       rS rSS	 jrS
 r\(       a	  S rSrU =r$ SrU =r$ )SequenceGenerator   a  
Base class used by word & phrase generators.

These objects take a series of options, corresponding
to those of the :func:`generate` function.
They act as callables which can be used to generate a password
or a list of 1+ passwords. They also expose some read-only
informational attributes.

Parameters
----------
:param entropy:
    Optionally specify the amount of entropy the resulting passwords
    should contain (as measured with respect to the generator itself).
    This will be used to auto-calculate the required password size.

:param length:
    Optionally specify the length of password to generate,
    measured as count of whatever symbols the subclass uses (characters or words).
    Note if ``entropy`` requires a larger minimum length,
    that will be used instead.

:param rng:
    Optionally provide a custom RNG source to use.
    Should be an instance of :class:`random.Random`,
    defaults to :class:`random.SystemRandom`.

Attributes
----------
.. autoattribute:: length
.. autoattribute:: symbol_count
.. autoattribute:: entropy_per_symbol
.. autoattribute:: entropy

Subclassing
-----------
Subclasses must implement the ``.__next__()`` method,
and set ``.symbol_count`` before calling base ``__init__`` method.
Nr    c                   > U R                   c   S5       eUc  Uc_  Uc  U R                  n[        R                  X5      nUS::  a  [	        S5      e[        [        XR                  -  5      5      nUb  X%:  a  UnXl        US:  a  [	        S5      eX l        Ub  X0l	        U(       aD  [        U [        5      [        4:X  a+  [        SSR                  UR                  5       5      -  5      e[         [        U ]F  " S0 UD6  g )	Nzsubclass must set .symbol_countr   z!`entropy` must be positive numberr#   z!`length` must be positive integerzUnexpected keyword(s): %srT    )symbol_countrequested_entropyentropy_aliasesgetrJ   r7   r	   entropy_per_symbollengthr   r+   rn   objectr6   rc   keyssuper__init__)selfentropyrw   r   kwds
min_length	__class__s         r*   r{   SequenceGenerator.__init__   s       ,O.OO, &.00%))';G!| !DEET',C,C"CDEJ~!4#!(A:@AA ?H M$(9:viG7$))DIIK:PPQQ/7$7r,   c                 .    [        U R                  S5      $ )zJ
Average entropy per symbol (assuming all symbols have equal probability)
r.   )r0   rr   r|   s    r*   rv   $SequenceGenerator.entropy_per_symbol  s    
 D%%q))r,   c                 4    U R                   U R                  -  $ )a  
Effective entropy of generated passwords.

This value will always be a multiple of :attr:`entropy_per_symbol`.
If entropy is specified in constructor, :attr:`length` will be chosen so
so that this value is the smallest multiple >= :attr:`requested_entropy`.
)rw   rv   r   s    r*   r}   SequenceGenerator.entropy  s     {{T4444r,   c                     [        S5      e)z;main generation function, should create one password/phrasezimplement in subclass)NotImplementedErrorr   s    r*   __next__SequenceGenerator.__next__)  s    !"9::r,   c                     Uc  [        U 5      $ [        U[        5      (       a%  [        U5       Vs/ s H  n[        U 5      PM     sn$ U[        L a  U $ [
        R                  " USS5      es  snf )z>
frontend used by genword() / genphrase() to create passwords
z<None>, int, or <iter>returns)nextr^   r   r   iterr   ExpectedTypeError)r|   r   _s      r*   __call__SequenceGenerator.__call__-  sd     ?:++(.w81DJ88_K''1I9UU	 9s   A,c                     U $ rV   rq   r   s    r*   __iter__SequenceGenerator.__iter__:  s    r,   c                 "    U R                  5       $ rV   )r   r   s    r*   r   SequenceGenerator.next>  s    ==?"r,   )rw   rs   r   NNNrV   )__name__
__module____qualname____firstlineno____doc__rw   rs   r   rr   r{   r   rv   r}   r   r   r   r   r   __static_attributes____classcell__r   s   @r*   rn   rn      sx    &X F ! C L
8F * * 5 5;V 	# 	# r,   rn   zH0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*?/>0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ2234679abcdefghjkmnpqrstuvwxyzACDEFGHJKMNPQRTUVWXYZ0123456789abcdef)ascii_72ascii_62ascii_50hexc                   N   ^  \ rS rSrSrSrSrS	U 4S jjr\S 5       r	S r
SrU =r$ )
WordGeneratori\  a  
Class which generates passwords by randomly choosing from a string of unique characters.

Parameters
----------
:param chars:
    custom character string to draw from.

:param charset:
    predefined charset to draw from.

:param \*\*kwds:
    all other keywords passed to the :class:`SequenceGenerator` parent class.

Attributes
----------
.. autoattribute:: chars
.. autoattribute:: charset
.. autoattribute:: default_charsets
r   Nc                    > U(       a  U(       a  [        S5      eO%U(       d  U R                  nU(       d   e[        U   nX l        [        USS9n[	        USS9  Xl        [        [        U ]"  " S0 UD6  g )Nz,`chars` and `charset` are mutually exclusivecharsrd   rq   )	r6   charsetr   r   rl   r   rz   r   r{   )r|   r   r   r~   r   s       r*   r{   WordGenerator.__init__~  so      NOO  ,,w$W-E50uG,
 	mT+3d3r,   c                 ,    [        U R                  5      $ rV   )r5   r   r   s    r*   rr   WordGenerator.symbol_count      4::r,   c                 X    [        U R                  U R                  U R                  5      $ rV   )r   r   r   rw   r   s    r*   r   WordGenerator.__next__  s     $((DJJ<<r,   )r   r   )NN)r   r   r   r   r   r   r   r{   r   rr   r   r   r   r   s   @r*   r   r   \  s9    2 G E
40  = =r,   r   c                 ,    [        SXS.UD6nU" U5      $ )a	  Generate one or more random passwords.

This function uses :mod:`random.SystemRandom` to generate
one or more passwords using various character sets.
The complexity of the password can be specified
by size, or by the desired amount of entropy.

Usage Example::

    >>> # generate a random alphanumeric string with 48 bits of entropy (the default)
    >>> from passlib import pwd
    >>> pwd.genword()
    'DnBHvDjMK6'

    >>> # generate a random hexadecimal string with 52 bits of entropy
    >>> pwd.genword(entropy=52, charset="hex")
    '310f1a7ac793f'

:param entropy:
    Strength of resulting password, measured in 'guessing entropy' bits.
    An appropriate **length** value will be calculated
    based on the requested entropy amount, and the size of the character set.

    This can be a positive integer, or one of the following preset
    strings: ``"weak"`` (24), ``"fair"`` (36),
    ``"strong"`` (48), and ``"secure"`` (56).

    If neither this or **length** is specified, **entropy** will default
    to ``"strong"`` (48).

:param length:
    Size of resulting password, measured in characters.
    If omitted, the size is auto-calculated based on the **entropy** parameter.

    If both **entropy** and **length** are specified,
    the stronger value will be used.

:param returns:
    Controls what this function returns:

    * If ``None`` (the default), this function will generate a single password.
    * If an integer, this function will return a list containing that many passwords.
    * If the ``iter`` constant, will return an iterator that yields passwords.

:param chars:

    Optionally specify custom string of characters to use when randomly
    generating a password. This option cannot be combined with **charset**.

:param charset:

    The predefined character set to draw from (if not specified by **chars**).
    There are currently four presets available:

    * ``"ascii_62"`` (the default) -- all digits and ascii upper & lowercase letters.
      Provides ~5.95 entropy per character.

    * ``"ascii_50"`` -- subset which excludes visually similar characters
      (``1IiLl0Oo5S8B``). Provides ~5.64 entropy per character.

    * ``"ascii_72"`` -- all digits and ascii upper & lowercase letters,
      as well as some punctuation. Provides ~6.17 entropy per character.

    * ``"hex"`` -- Lower case hexadecimal.  Providers 4 bits of entropy per character.

:returns:
    :class:`!unicode` string containing randomly generated password;
    or list of 1+ passwords if :samp:`returns={int}` is specified.
)rw   r}   rq   )r   r}   rw   r   r~   gens        r*   r   r     s!    L 
?v
?$
?Cw<r,   c                     [        U S5       nS U 5       n[        S U 5       5      nSSS5        [        R                  S[	        W5      U 5        U$ ! , (       d  f       N0= f)a  
load wordset from compressed datafile within package data.
file should be utf-8 encoded

:param asset_path:
    string containing  absolute path to wordset file,
    or "python.module:relative/file/path".

:returns:
    tuple of words, as loaded from specified words file.
zutf-8c              3   @   #    U  H  oR                  5       v   M     g 7frV   )striprY   s     r*   r3    _load_wordset.<locals>.<genexpr>  s     +zz||s   c              3   6   #    U  H  o(       d  M  Uv   M     g 7frV   rq   rY   s     r*   r3   r     s     3stdddss   
	Nz!loaded %d-element wordset from %r)rD   tupler
   debugr5   )
asset_pathfhr   wordss       r*   _load_wordsetr     sT     
*g	."++3s33 
/$ II13u:zJL' 
/	.s   A
A!c                   n   ^  \ rS rSrSrSrSrU 4S jrS rS r	S r
S r\S	 5       rS
 rS rS rSrU =r$ )WordsetDicti  z
Special mapping used to store dictionary of wordsets.
Different from a regular dict in that some wordsets
may be lazy-loaded from an asset path.
Nc                 J   > 0 U l         0 U l        [        [        U ]  " U0 UD6  g rV   )paths_loadedrz   r   r{   )r|   argsr~   r   s      r*   r{   WordsetDict.__init__%  s%    
k4)4848r,   c                      U R                   U   $ ! [         a     Of = fU R                  U   n[        U5      =o0R                   U'   U$ rV   )r   KeyErrorr   r   )r|   keyrF   r2   s       r*   __getitem__WordsetDict.__getitem__*  sP    	<<$$ 		zz#$1$$77S!s    
c                      X R                   U'   g)z+
set asset path to lazy-load wordset from.
N)r   )r|   r   rF   s      r*   set_pathWordsetDict.set_path3  s     

3r,   c                      X R                   U'   g rV   )r   )r|   r   r2   s      r*   __setitem__WordsetDict.__setitem__9  s    !Sr,   c                 |    X;   a*  U R                   U	 U R                  R                  US 5        g U R                  U	 g rV   )r   r   popr|   r   s     r*   __delitem__WordsetDict.__delitem__<  s0    ;S!JJNN3%

3r,   c                 f    [        U R                  5      nUR                  U R                  5        U$ rV   )r`   r   updater   )r|   ry   s     r*   _keysetWordsetDict._keysetC  s%    4<< DJJr,   c                 ,    [        U R                  5      $ rV   )r   r   r   s    r*   r   WordsetDict.__iter__I  s    DLL!!r,   c                 ,    [        U R                  5      $ rV   )r5   r   r   s    r*   __len__WordsetDict.__len__L  s    4<<  r,   c                 H    XR                   ;   =(       d    XR                  ;   $ rV   r   r   r   s     r*   __contains__WordsetDict.__contains__P  s    ll"7cZZ&77r,   r   )r   r   r   r   r   r   r   r{   r   r   r   r   propertyr   r   r   r   r   r   r   s   @r*   r   r     sW     E G9
"   
"!8 8r,   r   z%eff_long eff_short eff_prefixed bip39zpasslib:_data/wordsets/%s.txtc                   R   ^  \ rS rSrSrSrSrSrS
U 4S jjr\	S 5       r
S rS	rU =r$ )PhraseGeneratori_  a  class which generates passphrases by randomly choosing
from a list of unique words.

:param wordset:
    wordset to draw from.
:param preset:
    name of preset wordlist to use instead of ``wordset``.
:param spaces:
    whether to insert spaces between words in output (defaults to ``True``).
:param \*\*kwds:
    all other keywords passed to the :class:`SequenceGenerator` parent class.

.. autoattribute:: wordset
eff_longN c                 >  > Ub  Ub  [        S5      eO!Uc  U R                  nU(       d   e[        U   nXl        [        U[        5      (       d  [        U5      n[        USS9  X l        Uc  U R                  n[        USS9nX0l        [        [        U ]2  " S0 UD6  g )Nz,`words` and `wordset` are mutually exclusiver   r   rO   rq   )r6   wordsetr   r^   _sequence_typesr   rl   r   rO   r   rz   r   r{   )r|   r   r   rO   r~   r   s        r*   r{   PhraseGenerator.__init__~  s     " NOO # ,,w$W-E %11%LEuG,
 ;((CE* 	ot-55r,   c                 ,    [        U R                  5      $ rV   )r5   r   r   s    r*   rr   PhraseGenerator.symbol_count  r   r,   c                 x   ^  U 4S j[        T R                  5       5       nT R                  R                  U5      $ )Nc              3   n   >#    U  H*  nTR                   R                  TR                  5      v   M,     g 7frV   )r   choicer   )r1   r   r|   s     r*   r3   +PhraseGenerator.__next__.<locals>.<genexpr>  s'     J6I,,6Is   25)r   rw   rO   rc   )r|   r   s   ` r*   r   PhraseGenerator.__next__  s)    JfT[[6IJxx}}U##r,   )rO   r   r   r   )r   r   r   r   r   r   r   rO   r{   r   rr   r   r   r   r   s   @r*   r   r   _  sA    & G E C
6D  $ $r,   r   c                 ,    [        SXS.UD6nU" U5      $ )a]  Generate one or more random password / passphrases.

This function uses :mod:`random.SystemRandom` to generate
one or more passwords; it can be configured to generate
alphanumeric passwords, or full english phrases.
The complexity of the password can be specified
by size, or by the desired amount of entropy.

Usage Example::

    >>> # generate random phrase with 48 bits of entropy
    >>> from passlib import pwd
    >>> pwd.genphrase()
    'gangly robbing salt shove'

    >>> # generate a random phrase with 52 bits of entropy
    >>> # using a particular wordset
    >>> pwd.genword(entropy=52, wordset="bip39")
    'wheat dilemma reward rescue diary'

:param entropy:
    Strength of resulting password, measured in 'guessing entropy' bits.
    An appropriate **length** value will be calculated
    based on the requested entropy amount, and the size of the word set.

    This can be a positive integer, or one of the following preset
    strings: ``"weak"`` (24), ``"fair"`` (36),
    ``"strong"`` (48), and ``"secure"`` (56).

    If neither this or **length** is specified, **entropy** will default
    to ``"strong"`` (48).

:param length:
    Length of resulting password, measured in words.
    If omitted, the size is auto-calculated based on the **entropy** parameter.

    If both **entropy** and **length** are specified,
    the stronger value will be used.

:param returns:
    Controls what this function returns:

    * If ``None`` (the default), this function will generate a single password.
    * If an integer, this function will return a list containing that many passwords.
    * If the ``iter`` builtin, will return an iterator that yields passwords.

:param words:

    Optionally specifies a list/set of words to use when randomly generating a passphrase.
    This option cannot be combined with **wordset**.

:param wordset:

    The predefined word set to draw from (if not specified by **words**).
    There are currently four presets available:

    ``"eff_long"`` (the default)

        Wordset containing 7776 english words of ~7 letters.
        Constructed by the EFF, it offers ~12.9 bits of entropy per word.

        This wordset (and the other ``"eff_"`` wordsets)
        were `created by the EFF <https://www.eff.org/deeplinks/2016/07/new-wordlists-random-passphrases>`_
        to aid in generating passwords.  See their announcement page
        for more details about the design & properties of these wordsets.

    ``"eff_short"``

        Wordset containing 1296 english words of ~4.5 letters.
        Constructed by the EFF, it offers ~10.3 bits of entropy per word.

    ``"eff_prefixed"``

        Wordset containing 1296 english words of ~8 letters,
        selected so that they each have a unique 3-character prefix.
        Constructed by the EFF, it offers ~10.3 bits of entropy per word.

    ``"bip39"``

        Wordset of 2048 english words of ~5 letters,
        selected so that they each have a unique 4-character prefix.
        Published as part of Bitcoin's `BIP 39 <https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt>`_,
        this wordset has exactly 11 bits of entropy per word.

        This list offers words that are typically shorter than ``"eff_long"``
        (at the cost of slightly less entropy); and much shorter than
        ``"eff_prefixed"`` (at the cost of a longer unique prefix).

:param sep:
    Optional separator to use when joining words.
    Defaults to ``" "`` (a space), but can be an empty string, a hyphen, etc.

:returns:
    :class:`!unicode` string containing randomly generated passphrase;
    or list of 1+ passphrases if :samp:`returns={int}` is specified.
)r}   rw   rq   )r   r   s        r*   r   r     s!    B 
A'
AD
ACw<r,   rV   )r:   r   )=r   
__future__r   r   r   r   rB   collectionsr   collections.abcr   ImportErrormathr	   r
   r0   logging	getLoggerr   rK   rE   passlibr   passlib.utils.compatr   r   r   r   passlib.utilsr   r   r   passlib.utils.decorr   __all__dictrt   r+   r>   rD   listr   r   r`   	frozensetr_   r]   rl   rx   rn   r   r   r   r   r   r   splitnamer   r   r   rq   r,   r*   <module>r     sj   0 S R  #+. # g''1  	  C C 5 5 1  
 
  *"!RX;. -9
 u )(\I# I#h W N B 	 $E=% E=XGZ F98. 98| =  499;Dd$Cd$JK <K$' K$dbM  +*+s   D DD