
     hp                     t   d Z ddlmZmZmZmZ ddlZddlmZ 	 ddl	m
Z
 n# e$ r	 ddlm
Z
 Y nw xY wddlmZmZ ddlZ ej        e          ZddlZddlZddlmZ ddlmZmZmZmZ dd	lmZmZmZ dd
l m!Z! g dZ" e#ddddd          Z$d Z%d Z&d)dZ'e(e)fZ*e+e,fZ- e+            Z.d*dZ/ G d de0          Z1 e#dddd          Z2 G d de1          Z3d+d Z4d! Z5 G d" d#e
          Z6 e6            Z7d$8                                D ]Z9e7:                    e9d%e9z              G d& d'e1          Z;d+d(Z<dS ),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                 j    t          |           j        }||                    |          dz   d         S )z2return remaining classes in object's MRO after cls   N)type__mro__index)objclsmros      G/var/www/html/Sam_Eipo/venv/lib/python3.11/site-packages/passlib/pwd.py_superclassesr+   8   s0    
s))
Csyy~~a  !!    c                 f   	 t          |           }n# t          $ r d}Y nw xY wt          t                    }| D ]}||xx         dz  cc<   |$|                                }t          |          }nt          |          }|sdS t          |d          t          d |D                       |z  z
  S )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   <   K   | ]}|t          |d           z  V  dS )r.   N)logf).0values     r*   	<genexpr>z"_self_info_rate.<locals>.<genexpr>_   s/      JJ%utE1~~5JJJJJJr,   )len	TypeErrorr   intvaluessumr   r0   )sourcesizecountscharr7   s        r*   _self_info_rater=   >   s     6{{    F  t|6{{F## q a==3JJ6JJJJJTQQQs    !!c                 <   |r* t          j        |          t          |                     S t          j                            |           rt          | d          S |                     d          \  }}}|st          d|           t          j
        ||          S )a  
    :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)rE   encodingpackagesepsubpaths        r*   rC   rC   j   s      B)v))*:4*@*@AAA	w}}T  D$ NN3//GS' LjDHDK L L 	L(':::r,   r9   c                    t           }d}	 | |v rdS n# t          $ r d}Y nw xY wt          | t                    s-t	          t          |                     t	          |           k    r+|r'	 |                    |            n# t          $ r Y nw xY wdS t                      }t                      }| D ]}||v r|n|                    |           t          |          }d}t	          |          |k    rd}d                    d |d|         D                       }t	          |          |k    r|dt	          |          |z
  z  z  }t          d	|d
|          )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   N   K   | ] }t          t          |                    V  !d S N)reprstrr1   words     r*   r3   z!_ensure_unique.<locals>.<genexpr>   s.      BBTc$iiBBBBBBr,   Nz, ... plus %d others`z%` cannot contain duplicate elements: )
_ensure_unique_cacher5   
isinstance
_set_typesr4   setaddsortedjoinrI   )	r9   paramcachehashableseendupselemtruncdup_reprs	            r*   _ensure_uniquerj      s    !EHU??4     &*%% S[[)9)9S[[)H)H 			&!!!!     t 55D55D 3 34,,T2222$<<DE
4yy5yyBBT&5&\BBBBBH
4yy5*c$ii%.?@@ *eeXX' ( ( (s    !!)A? ?
BBc                        e Zd ZdZdZdZeZdZd fd	Ze	d             Z
e	d             Zd ZddZd	 Zerd
 Z xZS  xZS )SequenceGeneratoraY  
    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                 H   | j         
J d            ||g|| j        }t                              ||          }|dk    rt	          d          t          t          || j        z                      }|||k     r|}|| _        |dk     rt	          d          || _        ||| _	        |rVt          | t                    t          fk    r7t          dd                    |                                          z             t!          t          |           j        di | d S )	Nzsubclass must set .symbol_countr   z!`entropy` must be positive numberr#   z!`length` must be positive integerzUnexpected keyword(s): %srS    )symbol_countrequested_entropyentropy_aliasesgetrI   r6   r	   entropy_per_symbollengthr   r+   rl   objectr5   ra   keyssuper__init__)selfentropyrt   r   kwds
min_length	__class__s         r*   rx   zSequenceGenerator.__init__   s=     ,,.O,,, &.0%))'7;;G!|| !DEEET'D,C"CDDEEJ~*!4!4#!(A::@AAA ?DH  	RM$(9::viGG7$))DIIKK:P:PPQQQ/&&/77$77777r,   c                 ,    t          | j        d          S )zZ
        Average entropy per symbol (assuming all symbols have equal probability)
        r.   )r0   ro   ry   s    r*   rs   z$SequenceGenerator.entropy_per_symbol  s    
 D%q)))r,   c                      | j         | j        z  S )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`.
        )rt   rs   r   s    r*   rz   zSequenceGenerator.entropy  s     {T444r,   c                      t          d          )z;main generation function, should create one password/phrasezimplement in subclass)NotImplementedErrorr   s    r*   __next__zSequenceGenerator.__next__)  s    !"9:::r,   c                      |t                     S t          |t                    r fdt          |          D             S |t          u r S t          j        |dd          )zN
        frontend used by genword() / genphrase() to create passwords
        Nc                 .    g | ]}t                    S rn   )nextr1   _ry   s     r*   
<listcomp>z.SequenceGenerator.__call__.<locals>.<listcomp>4  s    8881DJJ888r,   z<None>, int, or <iter>returns)r   r\   r   r   iterr   ExpectedTypeError)ry   r   s   ` r*   __call__zSequenceGenerator.__call__-  sm     ?::++ 	V8888w8888__K'1I9UUUr,   c                     | S rU   rn   r   s    r*   __iter__zSequenceGenerator.__iter__:  s    r,   c                 *    |                                  S rU   )r   r   s    r*   r   zSequenceGenerator.next>  s    ==??"r,   NNNrU   )__name__
__module____qualname____doc__rt   rp   r   ro   rx   r   rs   rz   r   r   r   r   r   __classcell__r}   s   @r*   rl   rl      s       & &X F ! C L
8 8 8 8 8 8F * * * 5 5 5; ; ;V V V V    #	# 	# 	# 	# 	# 	# 	## # # #r,   rl   zH0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*?/>0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ2234679abcdefghjkmnpqrstuvwxyzACDEFGHJKMNPQRTUVWXYZ0123456789abcdef)ascii_72ascii_62ascii_50hexc                   H     e Zd ZdZdZdZd fd	Zed             Zd Z	 xZ
S )WordGeneratora  
    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                    |r|rt          d          n|s| j        }|sJ t          |         }|| _        t          |d          }t	          |d           || _         t          t          |           j        di | d S )Nz,`chars` and `charset` are mutually exclusivecharsrb   rn   )	r5   charsetr   r   rj   r   rw   r   rx   )ry   r   r   r{   r}   s       r*   rx   zWordGenerator.__init__~  s      	. P NOOOP  ,w$W-E5000uG,,,,
 	,mT""+33d33333r,   c                 *    t          | j                  S rU   )r4   r   r   s    r*   ro   zWordGenerator.symbol_count      4:r,   c                 B    t          | j        | j        | j                  S rU   )r   r   r   rt   r   s    r*   r   zWordGenerator.__next__  s     $(DJ<<<r,   )NN)r   r   r   r   r   r   rx   r   ro   r   r   r   s   @r*   r   r   \  s         2 G E
4 4 4 4 4 40   = = = = = = =r,   r   c                 6    t          d|| d|} ||          S )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.
    )rt   rz   rn   )r   rz   rt   r   r{   gens        r*   r   r     s-    L 
?vw
?
?$
?
?C3w<<r,   c                     t          | d          5 }d |D             }t          d |D                       }ddd           n# 1 swxY w Y   t                              dt	          |          |            |S )a2  
    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   >   K   | ]}|                                 V  d S rU   )striprX   s     r*   r3   z _load_wordset.<locals>.<genexpr>  s*      ++tzz||++++++r,   c              3      K   | ]}||V  	d S rU   rn   rX   s     r*   r3   z _load_wordset.<locals>.<genexpr>  s'      33td3d333333r,   Nz!loaded %d-element wordset from %r)rC   tupler
   debugr4   )
asset_pathfhr   wordss       r*   _load_wordsetr     s     
*g	.	. 4"+++++33s333334 4 4 4 4 4 4 4 4 4 4 4 4 4 4$ II13u::zJJJLs   &AA
Ac                   j     e Zd ZdZdZdZ fdZd Zd Zd Z	d Z
ed             Zd	 Zd
 Zd Z xZS )WordsetDictz
    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                 d    i | _         i | _         t          t          |           j        |i | d S rU   )paths_loadedrw   r   rx   )ry   argsr{   r}   s      r*   rx   zWordsetDict.__init__%  s9    
)k4  )48488888r,   c                     	 | j         |         S # t          $ r Y nw xY w| j        |         }t          |          x}| j         |<   |S rU   )r   KeyErrorr   r   )ry   keyrE   r2   s       r*   __getitem__zWordsetDict.__getitem__*  s]    	<$$ 	 	 	D	z#$1$$7$77S!s    
c                     || j         |<   dS )z;
        set asset path to lazy-load wordset from.
        N)r   )ry   r   rE   s      r*   set_pathzWordsetDict.set_path3  s     
3r,   c                     || j         |<   d S rU   )r   )ry   r   r2   s      r*   __setitem__zWordsetDict.__setitem__9  s    !Sr,   c                 h    || v r%| j         |= | j                            |d            d S | j        |= d S rU   )r   r   popry   r   s     r*   __delitem__zWordsetDict.__delitem__<  s>    $;;S!JNN3%%%%%
3r,   c                 b    t          | j                  }|                    | j                   |S rU   )r^   r   updater   )ry   rv   s     r*   _keysetzWordsetDict._keysetC  s*    4<  DJr,   c                 *    t          | j                  S rU   )r   r   r   s    r*   r   zWordsetDict.__iter__I  s    DL!!!r,   c                 *    t          | j                  S rU   )r4   r   r   s    r*   __len__zWordsetDict.__len__L  s    4<   r,   c                 &    || j         v p|| j        v S rU   )r   r   r   s     r*   __contains__zWordsetDict.__contains__P  s    dl"7cTZ&77r,   )r   r   r   r   r   r   rx   r   r   r   r   propertyr   r   r   r   r   r   s   @r*   r   r     s          E G9 9 9 9 9
    " " "        X
" " "! ! !8 8 8 8 8 8 8r,   r   z%eff_long eff_short eff_prefixed bip39zpasslib:_data/wordsets/%s.txtc                   L     e Zd ZdZdZdZdZd fd	Zed             Z	d Z
 xZS )	PhraseGeneratora  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                 l   ||t          d          n|| j        }|sJ t          |         }|| _        t          |t                    st          |          }t          |d           || _        || j        }t          |d          }|| _         t          t          |           j        di | d S )Nz,`words` and `wordset` are mutually exclusiver   r   rN   rn   )r5   wordsetr   r\   _sequence_typesr   rj   r   rN   r   rw   r   rx   )ry   r   r   rN   r{   r}   s        r*   rx   zPhraseGenerator.__init__~  s     " NOOO # ,w$W-E %11 	!%LLEuG,,,,
 ;(CE*** 	.ot$$-5555555r,   c                 *    t          | j                  S rU   )r4   r   r   s    r*   ro   zPhraseGenerator.symbol_count  r   r,   c                 x      fdt           j                  D             } j                            |          S )Nc              3   V   K   | ]#}j                             j                  V  $d S rU   )r   choicer   r   s     r*   r3   z+PhraseGenerator.__next__.<locals>.<genexpr>  s3      JJ,,JJJJJJr,   )r   rt   rN   ra   )ry   r   s   ` r*   r   zPhraseGenerator.__next__  s:    JJJJfT[6I6IJJJx}}U###r,   r   )r   r   r   r   r   r   rN   rx   r   ro   r   r   r   s   @r*   r   r   _  s         & G E C
6 6 6 6 6 6D   $ $ $ $ $ $ $r,   r   c                 6    t          d| |d|} ||          S )am  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.
    )rz   rt   rn   )r   r   s        r*   r   r     s-    B 
A'&
A
AD
A
AC3w<<r,   rU   )r9   r   )=r   
__future__r   r   r   r   rA   collectionsr   collections.abcr   ImportErrormathr	   r
   r0   logging	getLoggerr   rJ   rD   passlibr   passlib.utils.compatr   r   r   r   passlib.utilsr   r   r   passlib.utils.decorr   __all__dictrq   r+   r=   rC   listr   r   r^   	frozensetr]   r[   rj   ru   rl   r   r   r   r   r   r   splitnamer   r   r   rn   r,   r*   <module>r      s   0 0 S R R R R R R R R R R R  # # # # # #+....... + + +********+ # " " " " " " " 'g'11     				       C C C C C C C C C C C C 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1   $ 
 
    *" " "!R !R !RX; ; ; ;. -9
 suu )( )( )( )(\I# I# I# I# I# I# I# I#h 4W N B 	   $E= E= E= E= E=% E= E= E=XG G G GZ     F98 98 98 98 98. 98 98 98| ;==  499;; L LDd$Cd$JKKKK
K$ K$ K$ K$ K$' K$ K$ K$db b b b b bs   ! //