ó ö 5Xc@`s¤dZddlmZmZmZddlmZmZmZ m Z ddl m Z mZmZddlZejeƒZddlmZddlmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#ddl$m%Z%d d d d d ddddddddddddddddgZ&e!dƒZ'e!dƒZ(e!d ƒZ)e!d!ƒZ*e'e!d"ƒZ+e!d#ƒZ,e!d$ƒZ-e!d%ƒZ.eed&ƒƒZ/d'Z0d(Z1d"Z2e3ee/ƒƒZ4e5d)„Z6d*„Z7d+„Z8d,Z9d"Z:d-Z;d.„Z<d/„Z=d0„Z e6id1d26d3d46ƒZ>e2d5Z?d6„Zde@fd7„ƒYZAdeAfd8„ƒYZBeBe)ƒZCeBe)d9eDƒZEeBe*d9eDƒZFdS(:sC passlib.utils.binary - binary data encoding/decoding/manipulation i(tabsolute_importtdivisiontprint_function(t b64encodet b64decodet b32decodet b32encode(t b2a_base64t a2b_base64tErrorN(texc( tPY3t bascii_to_strtirangetimaptiter_byte_charstjoin_byte_valuestjoin_byte_elemst nextgettertsuppress_causetutunicodetunicode_or_bytes_types(tmemoized_propertyt BASE64_CHARStPADDED_BASE64_CHARSt AB64_CHARSt HASH64_CHARSt BCRYPT_CHARSt HEX_CHARStLOWER_HEX_CHARStUPPER_HEX_CHARStALL_BYTE_VALUEStcompile_byte_translationt ab64_encodet ab64_decodet b64s_encodet b64s_decodeRRt Base64EnginetLazyBase64Engineth64th64bigtbcrypt64s@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/s@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./s@./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzs@./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789t=t0123456789abcdefABCDEFt0123456789ABCDEFt0123456789abcdefittcC`s|dkrt}n9t|tƒr7t|ƒdks=t‚tt|ƒƒ}x»|jƒD]­\}}t|t ƒr†t |ƒ}nt|t ƒr±d|ko¬dkns·t‚t|t ƒrØ|j dƒ}nt|tƒrùt|ƒdksÿt‚||| 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. iÿiitasciiiN(tNonet_TRANSLATE_SOURCEt isinstancetbytestlentAssertionErrortlistRtitemsRtordtintRtencodetB_EMPTYtjoin(tmappingtsourcettargettktv((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyR!ns  '1'cC`st|ƒjtƒS(sr encode using shortened base64 format which omits padding & whitespace. uses default ``+/`` altchars. (Rtrstript _BASE64_STRIP(tdata((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyR$scC`sât|tƒrKy|jdƒ}WqKtk rGttdƒƒ‚qKXnt|ƒd@}|dkrjn>|dkrƒ|t7}n%|dkrœ|t7}n tdƒ‚yt |ƒSWn%t k rÝ}tt |ƒƒ‚nXdS(sq decode from shortened base64 format which omits padding & whitespace. uses default ``+/`` altchars. R1s4string argument should contain only ASCII charactersiiisinvalid base64 inputN( R4RR<tUnicodeEncodeErrorRt ValueErrorR6t _BASE64_PAD2t _BASE64_PAD1Rt_BinAsciiErrort TypeError(RFtoffterr((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyR%–s"       s= s==cC`st|ƒjddƒS(s® encode using shortened base64 format which omits padding & whitespace. uses custom ``./`` altchars. it is primarily used by Passlib's custom pbkdf2 hashes. t+t.(R$treplace(RF((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyR"¹scC`sat|tƒrKy|jdƒ}WqKtk rGttdƒƒ‚qKXnt|jddƒƒS(sã 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. R1s4string argument should contain only ASCII charactersRPRO(R4RR<RGRRHR%RQ(RF((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyR#Âs  cC`stt|ƒjtƒƒS(sh wrapper around :func:`base64.b32encode` which strips padding, and returns a native string. (R t _b32encodeRDtB_EQUAL(R@((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyRÕstBt8tOt0icC`set|tƒr!|jdƒ}n|jtƒ}t|ƒd@}|rX|t| 7}nt|tƒS(s„ wrapper around :func:`base64.b32decode` which handles common mistyped chars. padding optional, ignored if present. R1i( R4RR<t translatet_b32_translateR6t_b32_decode_padt _b32decodetTrue(R@t remainder((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyRåscB`s:eZdZdZdZdZdZdZdZ e d„Z e d„ƒZ d„Zd„Zd„Zd„Zd„Zd„Zd „Zed „ƒZed „ƒZd „Zd „Zd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z!d„Z"d„Z#d„Z$d„Z%d„Z&d„Z'RS(scProvides 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. cC`st|tƒr!|jdƒ}n$t|tƒsEtj|dƒ‚nt|ƒdkrftdƒ‚ntt|ƒƒdkrtdƒ‚n||_ |j |_ t d„t |ƒDƒƒ}|j |_||_|rô|j|_|j|_n|j|_|j|_dS(Nslatin-1tcharmapi@s'charmap must be 64 characters in lengths-charmap must not contain duplicate characterscs`s!|]\}}||fVqdS(N((t.0tidxtvalue((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pys ]s(R4RR<R5R tExpectedStringErrorR6RHtsettbytemapt __getitem__t _encode64tdictt enumeratet _decode64tbigt_encode_bytes_bigt _encode_bytest_decode_bytes_bigt _decode_bytest_encode_bytes_littlet_decode_bytes_little(tselfR^Rjtlookup((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt__init__Qs$      cC`s|jjdƒS(scharmap as unicodeslatin-1(Rdtdecode(Rq((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyR^sscC`s¨t|tƒs+tdt|ƒfƒ‚ntt|ƒdƒ\}}tratt|ƒƒ}ntd„|Dƒƒ}|j |||ƒ}t t |j |ƒƒ}|S(s‹encode bytes to base64 string. :arg source: byte string to encode. :returns: byte string containing encoded data. ssource must be bytes, not %sics`s|]}t|ƒVqdS(N(R:(R_telem((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pys ‡s( R4R5RLttypetdivmodR6R RtiterRlRRRf(RqR@tchunksttailt next_valuetgentout((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt encode_bytes{scc`sód}xq||kry|ƒ}|ƒ}|ƒ}|d@V|d@d>|d?BV|d@d>|d?BV|d?V|d7}q W|rï|ƒ}|dkrª|d@V|d?Vqï|dks¼t‚|ƒ}|d@V|d@d>|d?BV|d?Vnd S( s>helper used by encode_bytes() to handle little-endian encodingii?iiiiiiN(R7(RqR{RyRzR`tv1tv2tv3((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyRos(           cc`sûd}xq||kry|ƒ}|ƒ}|ƒ}|d?V|d@d>|d?BV|d@d>|d?BV|d@V|d7}q W|r÷|ƒ}|dkr®|d?V|d@d>Vq÷|dksÀt‚|ƒ}|d?V|d@d>|d?BV|d@d>Vnd S( s;helper used by encode_bytes() to handle big-endian encodingiiiiiii?iN(R7(RqR{RyRzR`RR€R((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyRk·s(          cC`sÊt|tƒs+tdt|ƒfƒ‚ntt|ƒdƒ\}}|dkratdƒ‚ntt|j |ƒƒ}yt |j |||ƒƒSWn-t k rÅ}td|j dfƒ‚nXdS(sdecode bytes from base64 string. :arg source: byte string to decode. :returns: byte string containing decoded data. ssource must be bytes, not %siis(input string length cannot be == 1 mod 4sinvalid character: %riN(R4R5RLRvRwR6RHRRRiRRntKeyErrortargs(RqR@RyRzR{RN((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt decode_bytesâs c c`sÛd}xu||kr}|ƒ}|ƒ}|ƒ}|ƒ}||d@d>BV|d?|d@d>BV|d?|d>BV|d7}q W|r×|ƒ}|ƒ}||d@d>BV|dkr×|ƒ}|d?|d@d>BVq×ndS( s>helper used by decode_bytes() to handle little-endian encodingiiiiiiiN(( RqR{RyRzR`RR€Rtv4((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyRpøs"        c c`sÛd}xu||kr}|ƒ}|ƒ}|ƒ}|ƒ}|d>|d?BV|d@d>|d?BV|d@d>|BV|d7}q W|r×|ƒ}|ƒ}|d>|d?BV|dkr×|ƒ}|d@d>|d?BVq×ndS( s;helper used by decode_bytes() to handle big-endian encodingiiiiiiiN(( RqR{RyRzR`RR€RR…((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyRms"        c`sUt‡fd†t|jƒDƒƒ}|j‡fd†t|jƒDƒƒt|ƒS(s2helper to generate set of valid last chars & bytesc3`s%|]\}}|ˆ@s|VqdS(N((R_titc(tbits(s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pys Gsc3`s%|]\}}|ˆ@s|VqdS(N((R_R†R‡(Rˆ(s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pys Hs(RcRhRdtupdateR^t frozenset(RqRˆtpset((Rˆs8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt __make_padsetEs%&cC`s)|jrdnd}||j|ƒfS(sDmask to clear padding bits, and valid last bytes (for strings 2 % 4)iii<(Rjt_Base64Engine__make_padset(RqRˆ((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt _padinfo2KscC`s)|jrdnd}||j|ƒfS(sDmask to clear padding bits, and valid last bytes (for strings 3 % 4)iii0(RjR(RqRˆ((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt _padinfo3RscC`s0t|ƒd@}|dkr.|j\}}n:|dkrL|j\}}n|s\t|fStdƒ‚|d}||krˆt|fSt|tƒrÒ|j}||j|ƒ|@}||kst dƒ‚nL|j |j |ƒ|@ƒ}||kst dƒ‚t rt |gƒ}nt|d |fS(shelper 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. iissource length must != 1 mod 4iÿÿÿÿs%failed to generate valid padding char(R6RŽRtFalseRHR4RR^tindexR7RfRiR R5R\(RqR@Rztmasktpadsettlasttcm((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pytcheck_repair_unusedYs(         cC`s|j|ƒdS(Ni(R–(RqR@((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt repair_unused‚sc`sTtˆtƒs+tdtˆƒfƒ‚nt‡fd†|Dƒƒ}|j|ƒS(s>encode byte string, first transposing source using offset listssource must be bytes, not %sc3`s|]}ˆ|VqdS(N((R_RM(R@(s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pys ˜s(R4R5RLRvRR~(RqR@toffsetsttmp((R@s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pytencode_transposed_bytes”scC`sV|j|ƒ}dgt|ƒ}x't||ƒD]\}}|||||ƒ}q WWn$t k råtd|fƒ‚nX|r|rÿ||L}q|d|>dM}n|S(s«decode 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`` ssource must be bytes, not %sissource must be %d charsisinvalid character in string: %ri( R4R5RLRvRjR6RHRitreversedR‚( RqR@RˆRjtpadtcharsRtR}R‡((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt _decode_int©s&     cC`s”t|tƒs+tdt|ƒfƒ‚nt|ƒdkrLtdƒ‚ntr_|d}ny|j|ƒSWntk rtdƒ‚nXdS(s(decode single character -> 6 bit integerssource must be bytes, not %sissource must be exactly 1 byteisinvalid characterN( R4R5RLRvR6RHR RiR‚(RqR@((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt decode_int6Ñs  cC`sÆt|tƒs+tdt|ƒfƒ‚nt|ƒdkrLtdƒ‚n|j}yM|jr||dƒ||dƒd>S||dƒ||dƒd>SWntk rÁtdƒ‚nXdS( s'decodes 2 char string -> 12-bit integerssource must be bytes, not %sissource must be exactly 2 bytesiiisinvalid characterN( R4R5RLRvR6RHRiRjR‚(RqR@Rt((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt decode_int12ßs   $ cC`st|tƒs+tdt|ƒfƒ‚nt|ƒdkrLtdƒ‚n|j}y•|jr¥||dƒ||dƒd>||dƒd>||d ƒd >S||d ƒ||dƒd>||dƒd>||dƒd >SWntk r td ƒ‚nXd S( s'decodes 4 char string -> 24-bit integerssource must be bytes, not %sissource must be exactly 4 bytesiiiii iisinvalid characterN( R4R5RLRvR6RHRiRjR‚(RqR@Rt((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt decode_int24îs  DH cC`s|j|dƒS(s&decode 5 char string -> 30 bit integeri(R¢(RqR@((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt decode_int30ÿscC`s|j|dƒS(s±decode 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. i@(R¢(RqR@((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt decode_int64sc`s‘ˆdkstdƒ‚| d}||7}|jrYt|dddƒ}ˆ|K‰ntd|dƒ}tt|j‡fd†|DƒƒƒS(sÕencode 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))``. iscaller did not sanitize inputiiúÿÿÿc3`s|]}ˆ|?d@VqdS(i?N((R_RM(Ra(s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pys "s(R7RjR RRRf(RqRaRˆR titr((Ras8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt _encode_ints      cC`sP|dks|dkr'tdƒ‚ntr?|j||d!S|j|ƒSdS(s0encodes 6-bit integer -> single hash64 characterii?svalue out of rangeiN(RHR RdRf(RqRa((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt encode_int6(s cC`sm|dks|dkr'tdƒ‚n|d@|d?d@g}|jrWt|ƒ}ntt|j|ƒƒS(s'encodes 12-bit integer -> 2 char stringiiÿsvalue out of rangei?i(RHRjRŸRRRf(RqRatraw((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt encode_int121s  cC`sƒ|dks|dkr'tdƒ‚n|d@|d?d@|d?d@|d?d@g}|jrmt|ƒ}ntt|j|ƒƒS(s'encodes 24-bit integer -> 4 char stringiiÿÿÿsvalue out of rangei?ii i(RHRjRŸRRRf(RqRaR«((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt encode_int24:s cC`s7|dks|dkr'tdƒ‚n|j|dƒS(s&decode 5 char string -> 30 bit integeriiÿÿÿ?svalue out of rangei(RHR©(RqRa((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt encode_int30DscC`s7|dks|dkr'tdƒ‚n|j|dƒS(s±encode 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. ilÿÿÿÿsvalue out of rangei@(RHR©(RqRa((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt encode_int64JsN((t__name__t __module__t__doc__R2RdRjRfRiRlRnRRstpropertyR^R~RoRkR„RpRmRRRŽRR–R—RšRžR¢R£R¤R¥R¦R§R©RªR¬R­R®R¯(((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyR&ýsD? "  ' +  # *  )    (      cB`s/eZdZdZd„Zd„Zd„ZRS(s<Base64Engine which delays initialization until it's accessedcO`s||f|_dS(N(t _lazy_opts(RqRƒtkwds((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyRs\scC`s;|j\}}tt|ƒj||Ž|`t|_dS(N(R´tsuperR'RsR&t __class__(RqRƒRµ((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyt _lazy_init_scC`s,|jdƒs|jƒntj||ƒS(Nt_(t startswithR¸tobjectt__getattribute__(Rqtattr((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyR¼es N(R°R±R²R2R´RsR¸R¼(((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pyR'Xs   Rj(GR²t __future__RRRtbase64RRRR[RRRtbinasciiRRR RKtloggingt getLoggerR°tlogtpasslibR tpasslib.utils.compatR R R RRRRRRRRRtpasslib.utils.decorRt__all__RRRRRRRRR R=tB_NULLRSR8R3R2R!R$R%RERJRIR"R#RYRZR»R&R'R(R\R)R*(((s8/usr/lib/python2.7/site-packages/passlib/utils/binary.pytsn" R         !      ÿÿ]