a fWcz@sdZddlmZmZmZddlmZmZmZ m Z ddl m Z mZmZddlZeeZddlmZddlmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#ddl$m%Z%gd Z&e!d Z'e!d Z(e!d Z)e!d Z*e'e!dZ+e!dZ,e!dZ-e!dZ.eedZ/dZ0dZ1dZ2e3ee/Z4d0ddZ5ddZ6ddZ7dZ8dZ9dZ:ddZ;d d!Zd(d)ZGd*d+d+e?Z@Gd,d-d-e@ZAeAe)ZBeAe)d.d/ZCeAe*d.d/ZDdS)1zC passlib.utils.binary - binary data encoding/decoding/manipulation )absolute_importdivisionprint_function) b64encode b64decode b32decode b32encode) b2a_base64 a2b_base64ErrorN)exc) PY3 bascii_to_strirangeimapiter_byte_charsjoin_byte_valuesjoin_byte_elems nextgettersuppress_causeuunicodeunicode_or_bytes_types)memoized_property) BASE64_CHARSPADDED_BASE64_CHARS AB64_CHARS HASH64_CHARS BCRYPT_CHARS HEX_CHARSLOWER_HEX_CHARSUPPER_HEX_CHARSALL_BYTE_VALUEScompile_byte_translation ab64_encode ab64_decode b64s_encode b64s_decoderr Base64EngineLazyBase64Engineh64h64bigbcrypt64z@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/z@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./z@./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzz@./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=Z0123456789abcdefABCDEFZ0123456789ABCDEFZ0123456789abcdef=cCs|durtdd}n&t|tr,t|dks0Jtt|}|D]t\}}t|tr^t|}t|t r~d|kr|dksnJt|t r| d}t|trt|dksJ|||<qDt |S)a return a 256-byte string for translating bytes using specified mapping. bytes not specified by mapping will be left alone. :param mapping: dict mapping input byte (str or int) -> output byte (str or int). :param source: optional existing byte translation string to use as base. (must be 255-length byte string). defaults to identity mapping. :returns: 255-length byte string for passing to bytes().translate. Nrr.ascii)_TRANSLATE_SOURCE isinstancebyteslenlistritemsrordintrencodeB_EMPTYjoin)mappingsourcetargetkvrE8/usr/lib/python3.9/site-packages/passlib/utils/binary.pyr#ns  $   r#cCst|tS)zr encode using shortened base64 format which omits padding & whitespace. uses default ``+/`` altchars. )r rstrip _BASE64_STRIPdatarErErFr&sr&c Cst|tr8z|d}Wnty6ttdYn0t|d@}|dkrNn,|dkr`|t7}n|dkrr|t7}ntdz t |WSt y}ztt |WYd}~n d}~00dS)zq decode from shortened base64 format which omits padding & whitespace. uses default ``+/`` altchars. r34string argument should contain only ASCII charactersrzinvalid base64 inputN) r6rr=UnicodeEncodeErrorr ValueErrorr8 _BASE64_PAD2 _BASE64_PAD1r _BinAsciiError TypeError)rJofferrrErErFr's"      r's= s==cCst|ddS)z encode using shortened base64 format which omits padding & whitespace. uses custom ``./`` altchars. it is primarily used by Passlib's custom pbkdf2 hashes. +.)r&replacerIrErErFr$sr$cCsHt|tr8z|d}Wnty6ttdYn0t|ddS)z decode from shortened base64 format which omits padding & whitespace. uses custom ``./`` altchars, but supports decoding normal ``+/`` altchars as well. it is primarily used by Passlib's custom pbkdf2 hashes. r3rKrWrV)r6rr=rNrrOr'rXrIrErErFr%s   r%cCstt|tS)zh wrapper around :func:`base64.b32encode` which strips padding, and returns a native string. )r _b32encoderGB_EQUALrArErErFrsrBO)80cCsJt|tr|d}|t}t|d@}|r@|td| 7}t|dS)z wrapper around :func:`base64.b32decode` which handles common mistyped chars. padding optional, ignored if present. r3NT)r6rr= translate_b32_translater8_b32_decode_pad _b32decode)rAZ remainderrErErFrs    rc@seZdZdZdZdZdZdZdZdZ d:ddZ e ddZ dd Z d d Zd d ZddZddZddZddZeddZeddZddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Z d.d/Z!d0d1Z"d2d3Z#d4d5Z$d6d7Z%d8d9Z&dS);r(acProvides routines for encoding/decoding base64 data using arbitrary character mappings, selectable endianness, etc. :arg charmap: A string of 64 unique characters, which will be used to encode successive 6-bit chunks of data. A character's position within the string should correspond to its 6-bit value. :param big: Whether the encoding should be big-endian (default False). .. note:: This class does not currently handle base64's padding characters in any way what so ever. Raw Bytes <-> Encoded Bytes =========================== The following methods convert between raw bytes, and strings encoded using the engine's specific base64 variant: .. automethod:: encode_bytes .. automethod:: decode_bytes .. automethod:: encode_transposed_bytes .. automethod:: decode_transposed_bytes .. .. automethod:: check_repair_unused .. automethod:: repair_unused Integers <-> Encoded Bytes ========================== The following methods allow encoding and decoding unsigned integers to and from the engine's specific base64 variant. Endianess is determined by the engine's ``big`` constructor keyword. .. automethod:: encode_int6 .. automethod:: decode_int6 .. automethod:: encode_int12 .. automethod:: decode_int12 .. automethod:: encode_int24 .. automethod:: decode_int24 .. automethod:: encode_int64 .. automethod:: decode_int64 Informational Attributes ======================== .. attribute:: charmap unicode string containing list of characters used in encoding; position in string matches 6bit value of character. .. attribute:: bytemap bytes version of :attr:`charmap` .. attribute:: big boolean flag indicating this using big-endian encoding. NFcCst|tr|d}nt|ts,t|dt|dkr@tdtt|dkrXtd||_ |j |_ t ddt |D}|j |_||_|r|j|_|j|_n|j|_|j|_dS)Nlatin-1charmap@z'charmap must be 64 characters in lengthz-charmap must not contain duplicate characterscss|]\}}||fVqdSNrE).0idxvaluerErErF ]r/z(Base64Engine.__init__..)r6rr=r7r ZExpectedStringErrorr8rOsetbytemap __getitem__ _encode64dict enumerate _decode64big_encode_bytes_big _encode_bytes_decode_bytes_big _decode_bytes_encode_bytes_little_decode_bytes_little)selfrgrulookuprErErF__init__Qs$      zBase64Engine.__init__cCs |jdS)zcharmap as unicoderf)rodecode)r|rErErFrgsszBase64Engine.charmapcCstt|tstdt|ftt|d\}}tr@tt|}ntdd|D}| |||}t t |j |}|S)zencode bytes to base64 string. :arg source: byte string to encode. :returns: byte string containing encoded data. source must be bytes, not %srLcss|]}t|VqdSri)r;)rjelemrErErFrmr/z,Base64Engine.encode_bytes..) r6r7rStypedivmodr8r riterrwrrrq)r|rAchunkstail next_valuegenoutrErErF encode_bytes{s zBase64Engine.encode_bytesccsd}||krh|}|}|}|d@V|d@d>|d?BV|d@d>|d?BV|d?V|d7}q|r|}|dkr|d@V|d?Vn<|dksJ|}|d@V|d@d>|d?BV|d?Vd S) z>helper used by encode_bytes() to handle little-endian encodingr?rMrLr4NrEr|rrrrkv1v2v3rErErFrzs(       z!Base64Engine._encode_bytes_littleccsd}||krh|}|}|}|d?V|d@d>|d?BV|d@d>|d?BV|d@V|d7}q|r|}|dkr|d?V|d@d>Vn@|dksJ|}|d?V|d@d>|d?BV|d@d>Vd S) z;helper used by encode_bytes() to handle big-endian encodingrrMrLrrrrr4NrErrErErFrvs(      zBase64Engine._encode_bytes_bigc Cst|tstdt|ftt|d\}}|dkr>tdtt|j |}zt | |||WSt y}z td|j dfWYd}~n d}~00dS)zdecode bytes from base64 string. :arg source: byte string to decode. :returns: byte string containing decoded data. rrr4z(input string length cannot be == 1 mod 4zinvalid character: %rrN)r6r7rSrrr8rOrrrtrryKeyErrorargs)r|rArrrrUrErErF decode_bytess zBase64Engine.decode_bytesc csd}||krh|}|}|}|}||d@d>BV|d?|d@d>BV|d?|d>BV|d7}q|r|}|}||d@d>BV|dkr|}|d?|d@d>BVdS) z>helper used by decode_bytes() to handle little-endian encodingrrLrrMrrr4NrE r|rrrrkrrrZv4rErErFr{s" z!Base64Engine._decode_bytes_littlec csd}||krh|}|}|}|}|d>|d?BV|d@d>|d?BV|d@d>|BV|d7}q|r|}|}|d>|d?BV|dkr|}|d@d>|d?BVdS) z;helper used by decode_bytes() to handle big-endian encodingrrMrrrLrr4NrErrErErFrxs" zBase64Engine._decode_bytes_bigcsBtfddt|jD}|fddt|jDt|S)z2helper to generate set of valid last chars & bytesc3s|]\}}|@s|VqdSrirErjicbitsrErFrmGr/z-Base64Engine.__make_padset..c3s|]\}}|@s|VqdSrirErrrErFrmHr/)rnrsroupdaterg frozenset)r|rZpsetrErrFZ __make_padsetEszBase64Engine.__make_padsetcCs|jr dnd}|||fS)zDmask to clear padding bits, and valid last bytes (for strings 2 % 4)r<ru_Base64Engine__make_padsetr|rrErErF _padinfo2KszBase64Engine._padinfo2cCs|jr dnd}|||fS)zDmask to clear padding bits, and valid last bytes (for strings 3 % 4)rL0rrrErErF _padinfo3RszBase64Engine._padinfo3cCst|d@}|dkr |j\}}n(|dkr4|j\}}n|s@d|fStd|d}||vr`d|fSt|tr|j}||||@}||vsJdn2|| ||@}||vsJdt rt |g}d|dd|fS) ahelper to detect & clear invalid unused bits in last character. :arg source: encoded data (as ascii bytes or unicode). :returns: `(True, result)` if the string was repaired, `(False, source)` if the string was ok as-is. rLrMFzsource length must != 1 mod 4z%failed to generate valid padding charTN) r8rrrOr6rrgindexrqrtr r7)r|rArmaskZpadsetZlastcmrErErFcheck_repair_unusedYs(     z Base64Engine.check_repair_unusedcCs||dS)Nr4)rr|rArErErF repair_unusedszBase64Engine.repair_unusedcs<ttstdtftfdd|D}||S)z>encode byte string, first transposing source using offset listrc3s|]}|VqdSrirErjrTr[rErFrmr/z7Base64Engine.encode_transposed_bytes..)r6r7rSrrr)r|rAoffsetstmprEr[rFencode_transposed_bytess z$Base64Engine.encode_transposed_bytescCs<||}dgt|}t||D]\}}|||<q"t|S)zGdecode byte string, then reverse transposition described by offset listN)rr8zipr)r|rArrbufrTcharrErErFdecode_transposed_bytess   z$Base64Engine.decode_transposed_bytesc Cst|tstdt|f|j}| d}||d}t||krRtd|f|j}d}z*|rf|nt|D]}|d>||}qnWn t ytd|fYn0|r|r||L}n|d|>dM}|S)adecode base64 string -> integer :arg source: base64 string to decode. :arg bits: number of bits in resulting integer. :raises ValueError: * if the string contains invalid base64 characters. * if the string is not long enough - it must be at least ``int(ceil(bits/6))`` in length. :returns: a integer in the range ``0 <= n < 2**bits`` rrzsource must be %d charsrzinvalid character in string: %rr4) r6r7rSrrur8rOrtreversedr) r|rArrupadcharsrrrrErErF _decode_ints&      zBase64Engine._decode_intcCsht|tstdt|ft|dkr0tdtr<|d}z ||WStybtdYn0dS)z(decode single character -> 6 bit integerrr4zsource must be exactly 1 byterinvalid characterN) r6r7rSrr8rOr rtrrrErErF decode_int6s    zBase64Engine.decode_int6cCst|tstdt|ft|dkr0td|j}zF|jr\||d||dd>WS||d||dd>WSWntytdYn0dS) z'decodes 2 char string -> 12-bit integerrrMzsource must be exactly 2 bytesr4rrrN r6r7rSrr8rOrtrurr|rArrErErF decode_int12s  " zBase64Engine.decode_int12cCst|tstdt|ft|dkr0td|j}z|jr|||d||dd>||dd>||d d >WS||d ||dd>||dd>||dd >WSWntytd Yn0d S) z'decodes 4 char string -> 24-bit integerrrzsource must be exactly 4 bytesrLrMrr4 rrNrrrErErF decode_int24s&    zBase64Engine.decode_int24cCs ||dS)&decode 5 char string -> 30 bit integerrrrErErF decode_int30szBase64Engine.decode_int30cCs ||dS)zdecode 11 char base64 string -> 64-bit integer this format is used primarily by des-crypt & variants to encode the DES output value used as a checksum. rhrrrErErF decode_int64szBase64Engine.decode_int64csldksJd| d}||7}|jrBt|ddd}|Kn td|d}tt|jfdd|DS)zencode integer into base64 format :arg value: non-negative integer to encode :arg bits: number of bits to encode :returns: a string of length ``int(ceil(bits/6.0))``. rzcaller did not sanitize inputric3s|]}|?d@VqdS)rNrErrlrErFrm"r/z+Base64Engine._encode_int..)rurrrrq)r|rlrritrrErrF _encode_ints    zBase64Engine._encode_intcCs<|dks|dkrtdtr.|j||dS||SdS)z0encodes 6-bit integer -> single hash64 characterrrvalue out of ranger4N)rOr rorqr|rlrErErF encode_int6(s zBase64Engine.encode_int6cCsJ|dks|dkrtd|d@|d?d@g}|jr:t|}tt|j|S)z'encodes 12-bit integer -> 2 char stringrirrrrOrurrrrqr|rlrawrErErF encode_int121s zBase64Engine.encode_int12cCs^|dks|dkrtd|d@|d?d@|d?d@|d?d@g}|jrNt|}tt|j|S)z'encodes 24-bit integer -> 4 char stringrirrrrrrrrErErF encode_int24:szBase64Engine.encode_int24cCs$|dks|dkrtd||dS)rri?rrrOrrrErErF encode_int30DszBase64Engine.encode_int30cCs$|dks|dkrtd||dS)zencode 64-bit integer -> 11 char hash64 string this format is used primarily by des-crypt & variants to encode the DES output value used as a checksum. rlrrhrrrErErF encode_int64JszBase64Engine.encode_int64)F)'__name__ __module__ __qualname____doc__rorurqrtrwryr~propertyrgrrzrvrr{rxrrrrrrrrrrrrrrrrrrrrrErErErFr(sJD " '+#*  )(    r(cs4eZdZdZdZddZfddZddZZS) r)zZB_NULLrZr9r5r#r&r'rHrQrPr$r%rcrdrr(r)r*r+r,rErErErFsV  8 %    !  _