
     h                     :   d Z ddlmZ ddlmZmZmZ ddlm	Z	m
Z
 	 ddlmZ ddlmZ ddlmZ ddlmZ dd	lZdd	lZdd	lZ ej0                  e      Zdd	lZdd	lZdd	lZdd	lZdd	lZer	 dd	l Z ndd	l Z dd	l"Z"e rdd	l#Z#	 dd	l$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-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6 ddl7m8Z8m9Z9m:Z:m;Z;m<Z< ddl=m>Z>m?Z? ddlm@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZP g dZQ eR ej4                  eFrej                  nej                  d      dz         ZUg dZVddgZWddl=mXZX dZY eGd      ZZ eGd      Z[ eRej                  j                  d      xs d      Z^ G d de_      Z`eFr8ej                  j                  Zc edecej                  j                  g      Zfd Zgnd Zg	 	 djd!Zhd" Zid# ZjejZk	 dd$llmmZj dkd%Zndld&Zoe dld'Zod( ZpeFrd) Zqd* Zrndd+lmsZsmtZt d, Zqd- Zr e@eqd.        e@erd/       d0 Zud1 Zvd2 Zwd3Zx eGd4      Zydmd5Zzd6 Z{d7Z|e|j                  d8      Z~d9 Zd: Zd;Z eGd<      Zd= Zdnd>Zdod?ZeFrdod@ZndodAZ e@edB        e8dCdDE      dpdF       Z eddGj                               Z eddHj                               Z edddIg      ZdqdJZdK Z	 ddLlmZ dMZd4Ze$r0ePr.dNej$                  cxk  rdOk  rn n e$j&                         ZdMZnddPlmZ  e       Zd Z eGdQ      ZeFrdMZ	  edRdS       dT ZndMZdU Z	  e@edW       dX Ze%j8                  ZeZdY Z	  ej@                  dZ       dMZdmd[Zer ejH                         Zn ejL                   e             Zd\ Zd] Zd^Z e8dDd_d`a      dbefdc       ZddZde ZdfZdg Zdh Zdi Zy	# e$ r ddlmZ ddlmZ Y w xY w# e$ r d	Z d
Z!Y Yw xY w# e$ r d	Z$Y Xw xY w# e$ r Y "w xY w# e$ r d ZY  Y xY w# e$ r d	Zd Zd Zd Zd	ZdV ZY w xY w# e$ r d ZY w xY w)rz4passlib.utils -- helpers for writing password hashes    )JYTHON)
b2a_base64
a2b_base64Error)	b64encode	b64decode)Sequence)Iterable)lookup)update_wrapperNznot present under Jython)warn)BASE64_CHARS
AB64_CHARSHASH64_CHARSBCRYPT_CHARSBase64EngineLazyBase64Engineh64h64bigbcrypt64ab64_encodeab64_decodeb64s_encodeb64s_decode)deprecated_functiondeprecated_methodmemoized_propertyclasspropertyhybrid_method)ExpectedStringErrorExpectedTypeError)add_doc
join_bytesjoin_byte_valuesjoin_byte_elemsirangeimapPY3ujoin_unicodeunicodebyte_elem_value
nextgetterunicode_or_strunicode_or_bytes_typesget_method_functionsuppress_causePYPY)r   sys_bitsunix_crypt_schemesrounds_cost_valuesconsteqsaslprep	xor_bytesrender_bytesis_same_codecis_ascii_safeto_bytes
to_unicodeto_native_str	has_crypt
test_crypt
safe_crypttickrnggetrandbytes
getrandstrgenerate_passwordis_crypt_handleris_crypt_contexthas_rounds_infohas_salt_info   g      ?)sha512_cryptsha256_crypt
sha1_cryptbcrypt	md5_crypt
bsdi_crypt	des_cryptlinearlog2)MissingBackendError      PASSLIB_MAX_PASSWORD_SIZEi   c                   :    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
y	)
SequenceMixinz
    helper which lets result object act like a fixed-length sequence.
    subclass just needs to provide :meth:`_as_tuple()`.
    c                     t        d      )Nzimplement in subclass)NotImplementedErrorselfs    X/var/www/html/Resume-Scraper/venv/lib/python3.12/site-packages/passlib/utils/__init__.py	_as_tuplezSequenceMixin._as_tuple   s    !"9::rV   c                 4    t        | j                               S N)reprra   r^   s    r`   __repr__zSequenceMixin.__repr__       DNN$%%rV   c                 (    | j                         |   S rc   ra   )r_   idxs     r`   __getitem__zSequenceMixin.__getitem__   s    ~~$$rV   c                 4    t        | j                               S rc   )iterra   r^   s    r`   __iter__zSequenceMixin.__iter__   rf   rV   c                 4    t        | j                               S rc   )lenra   r^   s    r`   __len__zSequenceMixin.__len__   s    4>>#$$rV   c                 (    | j                         |k(  S rc   rh   r_   others     r`   __eq__zSequenceMixin.__eq__   s    ~~5((rV   c                 &    | j                  |       S rc   )rt   rr   s     r`   __ne__zSequenceMixin.__ne__   s    ;;u%%%rV   N)__name__
__module____qualname____doc__ra   re   rj   rm   rp   rt   rv    rV   r`   r[   r[      s*    ;&%&%)&rV   r[   c                     t        j                  t        |             j                  }|sy|j	                  |      }|r|j
                  t        vry|t        |      d      j
                  t        k(  S )*test if function accepts specified keywordFT)	inspect	signaturer0   
parametersgetkind_VAR_ANY_SETlist_VAR_KEYWORD)funckeyparamsargs       r`   accepts_keywordr      sa    ""#6t#<=HHjjo388</d6l2&',,<<rV   c                 z    t        j                  t        |             }||j                  v xs |j                  duS )r}   N)r   
getargspecr0   argskeywords)r   r   specs      r`   r   r      s5    !!"5d";<dii<4==#<<rV   Fc                 f   t        |t              r|g}t        | j                        }|r7t        |t              r|g}|D ]  |r|v r
|v s|j	                         ! |r|D ]  t        fd|D              r|r>t        |      D ]$  \  }}	t        |	      r nk|st        |	|      s$ nY t        |      }nL|rHt        t        |            D ].  \  }
}	t        |	|      st        |      |
z
  }||dz
     |	k(  sJ  n d}nd}|j                  |        |st        |      | _        yy)a  
    helper to update mixin classes installed in target class.

    :param target:
        target class whose bases will be modified.

    :param add:
        class / classes to install into target's base class list.

    :param remove:
        class / classes to remove from target's base class list.

    :param append:
        by default, prepends mixins to front of list.
        if True, appends to end of list instead.

    :param after:
        optionally make sure all mixins are inserted after
        this class / classes.

    :param before:
        optionally make sure all mixins are inserted before
        this class / classes.

    :param dryrun:
        optionally perform all calculations / raise errors,
        but don't actually modify the class.
    c              3   6   K   | ]  }t        |        y wrc   )
issubclass).0basemixins     r`   	<genexpr>z'update_mixin_classes.<locals>.<genexpr>   s     =t:dE*=      r   N)
isinstancetyper   	__bases__removeany	enumerater   ro   reversedinserttuple)targetaddr   appendbeforeafterdryrunbasesri   r   end_idxr   s              @r`   update_mixin_classesr      sU   < #te!!"E fd#XF 	$Eu|~U#		$  	%E=u== !*5!1 	%IC!%.*T6":	% e*C%.x%? MGT!$.!%j72$SU|t33 C  LLe$?	%D  < rV   c              #   ~  K   |dk  rt        d      t        | t              r(t        |       }d}||k  r||z   }| ||  |}||k  ryyt        | t              rHt        |       }	 t        j                  ||      }	 t        |      }t        j                  |f|       <t        d      # t        $ r Y yw xY ww)z8
    split iterable into chunks of <size> elements.
    r   zsize must be positive integerr   zsource must be iterableN)
ValueErrorr   r	   ro   r
   rl   	itertoolsislicenextStopIterationchain	TypeError)sourcesizeendinitr	chunk_itrfirsts           r`   batchr     s      ax899&(#&k#gDA1+A #g 
FH	%6l!((d3IY //5(I66  122	 ! s0   AB=	4B=>B. 	%B=.	B:7B=9B::B=c                    t        | t              rt        |t              st        d      d}n=t        | t              r"t        |t              st        d      t        }nt        d      t        |       t        |      k(  }|r| }d}|s|}d}|r!t        |      D ]  \  }}||z  z  } dk(  S t        |      D ]  \  }}t        |      t        |      z  z  }! dk(  S )a  Check two strings/bytes for equality.

    This function uses an approach designed to prevent
    timing analysis, making it appropriate for cryptography.
    a and b must both be of the same type: either str (ASCII only),
    or any type that supports the buffer protocol (e.g. bytes).

    Note: If a and b are of different lengths, or if an error occurs,
    a timing attack could theoretically reveal information about the
    types and lengths of a and b--but not their values.
    z)inputs must be both unicode or both bytesFr   r   )r   r+   r   bytesr(   ro   zipord)leftrightis_py3_bytes	same_sizetmpresultlrs           r`   r6   r6   ;  s    * $ %)GHH	D%	 %'GHHCDD Tc%j(I  sE? 	CAaa!eOF	
 Q; sE? 	&CAac!fs1vo%F	&Q;rV   )compare_digestc                     | j                         } | j                  |      r| dd } | sg S | j                  |      D cg c]  }|j                          c}S c c}w )zRsplit comma-separated string into list of elements,
    stripping whitespace.
    Nr~   )stripendswithsplit)r   sepelems      r`   
splitcommar     sQ     \\^Fs	&,ll3&79dTZZ\999s   Ac                    t        | t              st        dt        |             t        j
                  t        j                  t        fd| D              }t        j                  d|      }|st        S t        j                  } ||d         r* ||d         st        d|z         t        j                  }n|}t        j                  }t        j                  }t        j                   }t        j"                  }t        j$                  }	t        j&                  }
t        j(                  }t        j*                  }t        j,                  }|D ]  } |      rJ d        |      rJ d        ||      rt        d	|z          ||      rt        d
|z          ||      rt        d|z          ||      rt        d|z          |	|      rt        d|z          |
|      rt        d|z          ||      rt        d|z          ||      rt        d|z          ||      rt        d|z          ||      st        d|z          |S )a  Normalizes unicode strings using SASLPrep stringprep profile.

    The SASLPrep profile is defined in :rfc:`4013`.
    It provides a uniform scheme for normalizing unicode usernames
    and passwords before performing byte-value sensitive operations
    such as hashing. Among other things, it normalizes diacritic
    representations, removes non-printing characters, and forbids
    invalid characters such as ``\n``. Properly internationalized
    applications should run user passwords through this function
    before hashing.

    :arg source:
        unicode string to normalize & validate

    :param param:
        Optional noun identifying source parameter in error messages
        (Defaults to the string ``"value"``). This is mainly useful to make the caller's error
        messages make more sense contextually.

    :raises ValueError:
        if any characters forbidden by the SASLPrep profile are encountered.

    :raises TypeError:
        if input is not :class:`!unicode`

    :returns:
        normalized unicode string

    .. note::

        This function is not available under Jython,
        as the Jython stdlib is missing the :mod:`!stringprep` module
        (`Jython issue 1758320 <http://bugs.jython.org/issue1758320>`_).

    .. versionadded:: 1.6
    z"input must be unicode string, not c              3   N   K   | ]  } |      s |      rt         n|  y wrc   )_USPACE)r   cin_table_b1in_table_c12s     r`   r   zsaslprep.<locals>.<genexpr>  s+      
1~  ?)
s   "%NFKCr   r~   zmalformed bidi sequence in z$failed to strip B.1 in mapping stagez(failed to replace C.1.2 in mapping stagez$unassigned code points forbidden in z control characters forbidden in z$private use characters forbidden in z"non-char code points forbidden in zsurrogate codes forbidden in z!non-plaintext chars forbidden in z!non-canonical chars forbidden in z1display-modifying / deprecated chars forbidden inztagged characters forbidden in zforbidden bidi character in )r   r+   r   r   
stringprepr   r   r*   unicodedata	normalize_UEMPTYin_table_d1r   in_table_d2in_table_a1in_table_c21_c22in_table_c3in_table_c4in_table_c5in_table_c6in_table_c7in_table_c8in_table_c9)r   paramdatais_ral_charis_forbidden_bidi_charr   r   r   r   r   r   r   r   r   r   r   r   s                  @@r`   r7   r7     s^   X fg&f( ) 	) **L((K 

 
D   .D ((K4748$:UBCC!+!7!7 "- ((K!22((K((K((K((K((K((K((K Eq>I#II?N$NN q>CeKLLA?%GHHq>CeKLLq>AEIJJq><uDEEq>@5HIIq> @5HIIq> ,.34 5 5q>>FGG "!$;eCDD=E@ KrV   c                 &    t        dt        z         )zstub for saslprep()z>saslprep() support requires the 'stringprep' module, which is )r]   _stringprep_missing_reason)r   r   s     r`   r7   r7     s    ! #02L#M N 	NrV   c                     t        | t              r| j                  d      } | t        d |D              z  }|j	                  d      S )a  Peform ``%`` formating using bytes in a uniform manner across Python 2/3.

    This function is motivated by the fact that
    :class:`bytes` instances do not support ``%`` or ``{}`` formatting under Python 3.
    This function is an attempt to provide a replacement:
    it converts everything to unicode (decoding bytes instances as ``latin-1``),
    performs the required formatting, then encodes the result to ``latin-1``.

    Calling ``render_bytes(source, *args)`` should function roughly the same as
    ``source % args`` under Python 2.

    .. todo::
        python >= 3.5 added back limited support for bytes %,
        can revisit when 3.3/3.4 is dropped.
    latin-1c              3   b   K   | ]'  }t        |t              r|j                  d       n| ) yw)r   N)r   r   decode)r   r   s     r`   r   zrender_bytes.<locals>.<genexpr>,  s3      6), 6@U5KCJJy1!$% 6s   -/)r   r   r   r   encode)r   r   r   s      r`   r9   r9     sI      &% y)e 6046 6 6F==##rV   c                 .    t         j                  | d      S Nbig)int
from_bytesvalues    r`   bytes_to_intr   2  s    ~~eU++rV   c                 &    | j                  |d      S r   )r<   r   counts     r`   int_to_bytesr   4  s    ~~eU++rV   )hexlify	unhexlifyc                 ,    t        t        |       d      S )N   )r   r   r   s    r`   r   r   9  s    75>"%%rV   c                 *    t        d|dz  z  | z        S )Nz%%0%dxr   )r   r   s     r`   r   r   ;  s    (eQh/5899rV   z/decode byte string as single big-endian integerz/encode integer as single big-endian byte stringc                 V    t        t        |       t        |      z  t        |             S )z;Perform bitwise-xor of two byte strings (must be same size))r   r   ro   r   r   s     r`   r8   r8   A  s"    T*\%-@@#d)LLrV   c                 :    d|dz
  t        |       z  z   }| |z  d| S )zE
    repeat or truncate <source> string, so it has length <size>
    r   N)ro   r   r   mults      r`   repeat_stringr  E  s,     qS[((DTM5D!!rV   c                 H    d|dz
  t        |       z  z   }t        | |z  |      S )zN
    variant of repeat_string() which truncates to nearest UTF8 boundary.
    r   )ro   utf8_truncater  s      r`   utf8_repeat_stringr  M  s,     qS[((D$--rV        c                 ~    t        |       }||kD  r)|t        | t              rt        nt        }| |||z
  z  z   S | d| S )z>right-pad or truncate <source> string, so it has length <size>N)ro   r   r+   _UNULL_BNULL)r   r   padcurs       r`   right_pad_stringr  X  sF    
f+Ccz;&vw7&VCc48n$$et}rV   c                 6    t         t              st         t        d      t               }|dk  rt	        d||z         }||k\  r S t        |dz   |      }||k  r t         |         dz  dk7  rn|dz  }||k  r ||k(  sJ  d|  fd} |       sJ S )	a  
    helper to truncate UTF8 byte string to nearest character boundary ON OR AFTER <index>.
    returned prefix will always have length of at least <index>, and will stop on the
    first byte that's not a UTF8 continuation byte (128 - 191 inclusive).
    since utf8 should never take more than 4 bytes to encode known unicode values,
    we can stop after ``index+3`` is reached.

    :param bytes source:
    :param int index:
    :rtype: bytes
    r   r            r   Nc                      	 j                  d      } | j                  j                  d            sJ y# t        $ r Y yw xY w)Nutf-8T)r   UnicodeDecodeError
startswith)textr   r   s    r`   sanity_checkz#utf8_truncate.<locals>.sanity_check  sG    	==)D v}}W566 " 		s   7 	AA)r   r   r!   ro   maxminr,   )r   indexr   r  r   s   `   @r`   r
  r
  c  s    2 fe$x88 f+CqyAus{#| eai
C #+6%=)D0D8
 #+ | FU^F
 >MrV   s	    
 aA:#!asciic                 :    t         j                  |       t        k(  S )zRTest if codec is compatible with 7-bit ascii (e.g. latin-1, utf-8; but not utf-16))_ASCII_TEST_UNICODEr   _ASCII_TEST_BYTES)codecs    r`   is_ascii_codecr&    s    %%e,0AAArV   c                 n    | |k(  ry| r|syt        |       j                  t        |      j                  k(  S )z3Check if two codec names are aliases for same codecTF)_lookup_codecnamer  s     r`   r:   r:     s5    u}U##}U';'@'@@@rV   r     c                 d    t        | t              rt        nt        t	        fd| D              S )z<Check if string (bytes or unicode) contains only 7-bit asciic              3   (   K   | ]	  }|k    y wrc   r{   )r   r   r   s     r`   r   z is_ascii_safe.<locals>.<genexpr>  s     %q1u%s   )r   r   _B80_U80all)r   r   s    @r`   r;   r;     s$    65)tA%f%%%rV   c                     |sJ t        | t              r0|r,t        ||      s | j                  |      j	                  |      S | S t        | t
              r| j	                  |      S t        | |      )a  Helper to normalize input to bytes.

    :arg source:
        Source bytes/unicode to process.

    :arg encoding:
        Target encoding (defaults to ``"utf-8"``).

    :param param:
        Optional name of variable/noun to reference when raising errors

    :param source_encoding:
        If this is specified, and the source is bytes,
        the source will be transcoded from *source_encoding* to *encoding*
        (via unicode).

    :raises TypeError: if source is not unicode or bytes.

    :returns:
        * unicode strings will be encoded using *encoding*, and returned.
        * if *source_encoding* is not specified, byte strings will be
          returned unchanged.
        * if *source_encoding* is specified, byte strings will be transcoded
          to *encoding*.
    )r   r   r:   r   r   r+   r    )r   encodingr   source_encodings       r`   r<   r<     sd    4 O&% =(#K==188BBM	FG	$}}X&&!&%00rV   c                     |sJ t        | t              r| S t        | t              r| j                  |      S t	        | |      )a  Helper to normalize input to unicode.

    :arg source:
        source bytes/unicode to process.

    :arg encoding:
        encoding to use when decoding bytes instances.

    :param param:
        optional name of variable/noun to reference when raising errors.

    :raises TypeError: if source is not unicode or bytes.

    :returns:
        * returns unicode strings unchanged.
        * returns bytes strings decoded using *encoding*
    )r   r+   r   r   r    r   r1  r   s      r`   r=   r=     s>    $ O&'"	FE	"}}X&&!&%00rV   c                     t        | t              r| j                  |      S t        | t              r| S t	        | |      rc   )r   r   r   r+   r    r4  s      r`   r>   r>     s7    fe$==**(M%fe44rV   c                     t        | t              r| S t        | t              r| j                  |      S t	        | |      rc   )r   r   r+   r   r    r4  s      r`   r>   r>     s7    fe$M(==**%fe44rV   a>  Take in unicode or bytes, return native string.

    Python 2: encodes unicode using specified encoding, leaves bytes alone.
    Python 3: leaves unicode alone, decodes bytes using specified encoding.

    :raises TypeError: if source is not unicode or bytes.

    :arg source:
        source unicode or bytes string.

    :arg encoding:
        encoding to use when encoding unicode or decoding bytes.
        this defaults to ``"utf-8"``.

    :param param:
        optional name of variable/noun to reference when raising errors.

    :returns: :class:`str` instance
    z1.6z1.7)
deprecatedremovedc                     t        | |d      S )z'deprecated, use to_native_str() insteadhash)r   )r>   )r   r1  s     r`   to_hash_strr;  $  s     88rV   z true t yes y on 1 enable enabledz#false f no n off 0 disable disablednonec                    |dv sJ t        | t              rK| j                         j                         }|t        v ry|t
        v ry|t        v r|S t        d|d|       t        | t              r| S | |S t        |       S )z\
    helper to convert value to boolean.
    recognizes strings such as "true", "false"
    )TFNTFzunrecognized z value: )	r   r/   lowerr   	_true_set
_false_set	_none_setr   bool)r   r<  r   cleans       r`   as_boolrD  -  s    
 &&&%/0##%IJIKuEFF	E4	 	E{rV   c                 t    t         st        | t              sy	 | j                  d       y# t        $ r Y yw xY w)z
    UT helper --
    test if value is safe to pass to crypt.crypt();
    under PY3, can't pass non-UTF8 bytes to crypt.crypt.
    Tr  F)crypt_accepts_bytesr   r   r   r  r   s    r`   is_safe_crypt_inputrG  G  s9     *UE":W s   + 	77)cryptT)   rK   r   )rI  r  r  )nullcontextz*:!   xxc                    t         rVt        | t              r| j                  d      } t        | v rt        d      t        |t              r|j                  d      }nst        | t              r/| }	 | j                  d      } | j                  d      |k(  sJ d       t        | v rt        d      t        |t              r|j                  d      }	 t        5  t        | |      }d d d        t        t              r|j                  d      }|r|d   t        v ry |S # t        $ r Y y w xY w# 1 sw Y   IxY w# t        $ r Y y w xY w)Nr  null character in secretr!  z"utf-8 spec says this can't happen!r   )rF  r   r+   r   r  r   r   r   r  _NULL_safe_crypt_lock_cryptOSError_invalid_prefixes)secretr:  origr   s       r`   rA   rA     s=   " fg.#]]73FV#$%?@@dG,;;w/D
 fe,!D$!'w!7
 "==1T9 E DEF?$%?@@dE*;;w/D% 2#FD1F2 &%(w/VAY*;;M3 . $#$2 2  	s<   0D D8 D,$D8 	D)(D),D51D8 8	EEc                 >   t        | t              r| j                  d      } t        | v rt	        d      t        |t              r|j                  d      }t
        5  t        | |      }d d d        sy |j                  d      }|d   t        v ry |S # 1 sw Y   +xY w)Nr  rN  r!  r   )	r   r+   r   rO  r   rP  rQ  r   rS  )rT  r:  r   s      r`   rA   rA     s    &'*w/ !;<<$({{7+! .-.]]7+Fay--M. .s   BBc                      y rc   r{   rT  r:  s     r`   rA   rA   ]  s    rV   a  Wrapper around stdlib's crypt.

    This is a wrapper around stdlib's :func:`!crypt.crypt`, which attempts
    to provide uniform behavior across Python 2 and 3.

    :arg secret:
        password, as bytes or unicode (unicode will be encoded as ``utf-8``).

    :arg hash:
        hash or config string, as ascii bytes or unicode.

    :returns:
        resulting hash as ascii unicode; or ``None`` if the password
        couldn't be hashed due to one of the issues:

        * :func:`crypt()` not available on platform.

        * Under Python 3, if *secret* is specified as bytes,
          it must be use ``utf-8`` or it can't be passed
          to :func:`crypt()`.

        * Some OSes will return ``None`` if they don't recognize
          the algorithm being used (though most will simply fall
          back to des-crypt).

        * Some OSes will return an error string if the input config
          is recognized but malformed; current code converts these to ``None``
          as well.
    c                 x    t        |t              sJ dt        |      z         |sJ d       t        | |      |k(  S )zcheck if :func:`crypt.crypt` supports specific hash
    :arg secret: password to test
    :arg hash: known hash of password to use as reference
    :returns: True or False
    z#hash must be unicode_or_str, got %szhash must be non-empty)r   r.   r   rA   rX  s     r`   r@   r@     sB     dN+ ;-T
:;)))fd#t++rV   c                     t        j                  d|       }|r0t        d |j                  d      j	                  d      D              S y)zhelper to parse version stringz(\d+(?:\.\d+)+)c              3   2   K   | ]  }t        |        y wrc   )r   )r   r   s     r`   r   z parse_version.<locals>.<genexpr>  s     A4SYAs   r   .N)researchr   groupr   )r   ms     r`   parse_versionra    s=    
		$f-AA1771:+;+;C+@AAArV   r   c           	         ddl m} t        | d      rt        | d      r	 | j                         } t        d      | t        t        d      rt        j                         ndt        t                     t        j                         t               t        r$t        j                  d	      j                  d
      ndfz  }t!         ||j#                  d            j%                         d      S # t        $ r | j                  d      } Y w xY w)z.generate prng seed value from system resourcesr   )sha512getstategetrandbitsi   z%s %s %s %.15f %.15f %sgetpidN    r   r  r  )hashlibrc  hasattrrd  r]   re  r)   osrf  idobjecttimerB   has_urandomurandomr   r   r   	hexdigest)r   rc  r  s      r`   genseedrq    s    uj!ge]&C	/NN$E
 &' r8,		$ 	68 			 -8

2i(Q#+
 
D( vdkk'*+557<<1 # 	/ %%g.E	/s   C, ,D	D	c                 B     st         S  fd}t         |             S )z]return byte-string containing *count* number of randomly generated bytes, using specified rngc               3   t   K   j                  dz        } d}|k  r| dz   | dz  } |dz  }|k  ry y w)Nr  r      r   )re  )r   r   r   rC   s     r`   helperzgetrandbytes.<locals>.helperM  sJ     q)%i$,aKEFA %is   288)_BEMPTYr$   )rC   r   ru  s   `` r`   rD   rD   B  s!      FH%%rV   c                      dk  rt        d      t              dk(  rt        d      dk(  rz  S  fd}t        t              rt	         |             S t         |             S )z|return string containing *count* number of chars/bytes, whose elements are drawn from specified charset, using specified rngr   zcount must be >= 0zalphabet must not be emptyr   c               3   |   K   j                  dz        } d}|k  r| z      | z  } |dz  }|k  ry y w)Nr   r   )	randrange)r   r   charsetr   lettersrC   s     r`   ru  zgetrandstr.<locals>.helperf  sR     a%0%i%'/**gEFA %is   6<<)r   ro   r   r+   r*   r%   )rC   rz  r   ru  r{  s   ``` @r`   rE   rE   W  sp     qy-..'lG!|566!| '7#FH%%vx((rV   42346789ABCDEFGHJKMNPQRTUVWXYZabcdefghjkmnpqrstuvwxyzz2.0z/passlib.pwd.genword() / passlib.pwd.genphrase())r7  r8  replacement
   c                 $    t        t        ||       S )aw  generate random password using given length & charset

    :param size:
        size of password.

    :param charset:
        optional string specified set of characters to draw from.

        the default charset contains all normal alphanumeric characters,
        except for the characters ``1IiLl0OoS5``, which were omitted
        due to their visual similarity.

    :returns: :class:`!str` containing randomly generated password.

    .. note::

        Using the default character set, on a OS with :class:`!SystemRandom` support,
        this function should generate passwords with 5.7 bits of entropy per character.
    )rE   rC   )r   rz  s     r`   rF   rF   v  s    , c7D))rV   )r)  setting_kwdscontext_kwdsverifyr:  identifyc                 4     t         fdt        D              S )z4check if object follows the :ref:`password-hash-api`c              3   6   K   | ]  }t        |        y wrc   ri  r   r)  objs     r`   r   z#is_crypt_handler.<locals>.<genexpr>       =dwsD!=r   )r/  _handler_attrsr  s   `r`   rG   rG          =n===rV   )needs_update	genconfiggenhashr  encryptr  c                 4     t         fdt        D              S )zOcheck if object appears to be a :class:`~passlib.context.CryptContext` instancec              3   6   K   | ]  }t        |        y wrc   r  r  s     r`   r   z#is_crypt_context.<locals>.<genexpr>  r  r   )r/  _context_attrsr  s   `r`   rH   rH     r  rV   c                 @    d| j                   v xr t        | dd      duS )z_check if handler provides the optional :ref:`rounds information <rounds-attributes>` attributesrounds
min_roundsNr  getattrhandlers    r`   rI   rI     s+    ,,, =G\40<>rV   c                 @    d| j                   v xr t        | dd      duS )z[check if handler provides the optional :ref:`salt information <salt-attributes>` attributessaltmin_salt_sizeNr  r  s    r`   rJ   rJ     s-    g*** @G_d34?ArV   )NNFNNF),r   rc   )r  r   N)r  r   )r!  )Nboolean)rz   passlib.utils.compatr   binasciir   r   r   _BinAsciiErrorbase64r   r   collections.abcr	   r
   ImportErrorcollectionscodecsr   r(  	functoolsr   r   r   logging	getLoggerrw   logmathrj  sysrandomr]  r   r   rm  r   	threadingtimeittypeswarningsr   passlib.utils.binaryr   r   r   r   r   r   r   r   r   r   r   r   r   passlib.utils.decorr   r   r   r   r   passlib.excr    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   __all__r   maxsizemaxintr3   r4   r5   rU   rv  r   r   environr   MAX_PASSWORD_SIZErl  r[   	ParameterVAR_KEYWORDr   setVAR_POSITIONALr   r   r   r   r6   str_consteqhmacr   r   r7   r9   r   r   r   r   r8   r  r  r  r  r  r
  r$  r   r#  r&  r:   r-  r.  r;   r<   r=   r>   r;  r   r?  r@  rA  rD  rG  rH  rQ  r?   rO  pypy_version_infoLockrP  crypt_needs_lockrJ  rS  rF  r   rA   r@   default_timertimerrB   ra  ro  rn  r]   rq  SystemRandomrC   RandomrD   rE   
_52charsetrF   r  rG   r  rH   rI   rJ   r{   rV   r`   <module>r     s"   : ( D D '%((
 + $   'g''1  	 
  		@
          ?M M M M M'\ xtxxs

A>DE   )  , 
B%
C& 

'BCKtL &F &4  $$00Lg&7&7&F&FGHL	==
 @E9>R(n3>8| 	.	:}@ N$, ,, ,&: G H G HM". 
	
6AL ( '..w7 BA y&
#1J14 55 	* u59 69 288:;	6<<>?
V	4s% IE Ti3+@+@MIM *9>>+   	5&=  %

 #	7D!+	^ #	  
  	<, 	,BJJqMK=B 
&


C &--	
"C
&*): D
u!RTz *T*2
>

>>
AK%  %$$$%&  @
%?"@  Ij
  		D  	("'	 _  FIz  Ks}   N' )N? =O =O *O8 	O) 4P 'N<;N<?	OOOOO&%O&)O52O58PPPP