diff --git a/Lib/base64.py b/Lib/base64.py --- a/Lib/base64.py +++ b/Lib/base64.py @@ -35,16 +35,17 @@ def _bytes_from_decode_data(s): return s.encode('ascii') except UnicodeEncodeError: raise ValueError('string argument should contain only ASCII characters') elif isinstance(s, bytes_types): return s else: raise TypeError("argument should be bytes or ASCII string, not %s" % s.__class__.__name__) + def _translate(s, altchars): if not isinstance(s, bytes_types): raise TypeError("expected bytes, not %s" % s.__class__.__name__) translation = bytearray(range(256)) for k, v in altchars.items(): translation[ord(k)] = v[0] return s.translate(translation) @@ -101,35 +102,38 @@ def b64decode(s, altchars=None, validate def standard_b64encode(s): """Encode a byte string using the standard Base64 alphabet. s is the byte string to encode. The encoded byte string is returned. """ return b64encode(s) + def standard_b64decode(s): """Decode a byte string encoded with the standard Base64 alphabet. s is the byte string to decode. The decoded byte string is returned. binascii.Error is raised if the input is incorrectly padded or if there are non-alphabet characters present in the input. """ return b64decode(s) + def urlsafe_b64encode(s): """Encode a byte string using a url-safe Base64 alphabet. s is the byte string to encode. The encoded byte string is returned. The alphabet uses '-' instead of '+' and '_' instead of '/'. """ return b64encode(s, b'-_') + def urlsafe_b64decode(s): """Decode a byte string encoded with the standard Base64 alphabet. s is the byte string to decode. The decoded byte string is returned. binascii.Error is raised if the input is incorrectly padded or if there are non-alphabet characters present in the input. @@ -170,27 +174,27 @@ def b32encode(s): quanta += 1 encoded = bytes() for i in range(quanta): # c1 and c2 are 16 bits wide, c3 is 8 bits wide. The intent of this # code is to process the 40 bits in units of 5 bits. So we take the 1 # leftover bit of c1 and tack it onto c2. Then we take the 2 leftover # bits of c2 and tack them onto c3. The shifts and masks are intended # to give us values of exactly 5 bits in width. - c1, c2, c3 = struct.unpack('!HHB', s[i*5:(i+1)*5]) - c2 += (c1 & 1) << 16 # 17 bits wide - c3 += (c2 & 3) << 8 # 10 bits wide - encoded += bytes([_b32tab[c1 >> 11], # bits 1 - 5 - _b32tab[(c1 >> 6) & 0x1f], # bits 6 - 10 - _b32tab[(c1 >> 1) & 0x1f], # bits 11 - 15 - _b32tab[c2 >> 12], # bits 16 - 20 (1 - 5) - _b32tab[(c2 >> 7) & 0x1f], # bits 21 - 25 (6 - 10) - _b32tab[(c2 >> 2) & 0x1f], # bits 26 - 30 (11 - 15) - _b32tab[c3 >> 5], # bits 31 - 35 (1 - 5) - _b32tab[c3 & 0x1f], # bits 36 - 40 (1 - 5) + c1, c2, c3 = struct.unpack('!HHB', s[i * 5:(i + 1) * 5]) + c2 += (c1 & 1) << 16 # 17 bits wide + c3 += (c2 & 3) << 8 # 10 bits wide + encoded += bytes([_b32tab[c1 >> 11], # bits 1 - 5 + _b32tab[(c1 >> 6) & 0x1f], # bits 6 - 10 + _b32tab[(c1 >> 1) & 0x1f], # bits 11 - 15 + _b32tab[c2 >> 12], # bits 16 - 20 (1 - 5) + _b32tab[(c2 >> 7) & 0x1f], # bits 21 - 25 (6 - 10) + _b32tab[(c2 >> 2) & 0x1f], # bits 26 - 30 (11 - 15) + _b32tab[c3 >> 5], # bits 31 - 35 (1 - 5) + _b32tab[c3 & 0x1f], # bits 36 - 40 (1 - 5) ]) # Adjust for any leftover partial quanta if leftover == 1: return encoded[:-6] + b'======' elif leftover == 2: return encoded[:-4] + b'====' elif leftover == 3: return encoded[:-3] + b'===' @@ -305,18 +309,18 @@ def b16decode(s, casefold=False): return binascii.unhexlify(s) # Legacy interface. This code could be cleaned up since I don't believe # binascii has any line length limitations. It just doesn't seem worth it # though. The files should be opened in binary mode. -MAXLINESIZE = 76 # Excluding the CRLF -MAXBINSIZE = (MAXLINESIZE//4)*3 +MAXLINESIZE = 76 # Excluding the CRLF +MAXBINSIZE = (MAXLINESIZE // 4) * 3 def encode(input, output): """Encode a file; input and output are binary files.""" while True: s = input.read(MAXBINSIZE) if not s: break while len(s) < MAXBINSIZE: @@ -344,30 +348,32 @@ def encodebytes(s): if not isinstance(s, bytes_types): raise TypeError("expected bytes, not %s" % s.__class__.__name__) pieces = [] for i in range(0, len(s), MAXBINSIZE): chunk = s[i : i + MAXBINSIZE] pieces.append(binascii.b2a_base64(chunk)) return b"".join(pieces) + def encodestring(s): """Legacy alias of encodebytes().""" import warnings warnings.warn("encodestring() is a deprecated alias, use encodebytes()", DeprecationWarning, 2) return encodebytes(s) def decodebytes(s): """Decode a bytestring of base-64 data into a bytestring.""" if not isinstance(s, bytes_types): raise TypeError("expected bytes, not %s" % s.__class__.__name__) return binascii.a2b_base64(s) + def decodestring(s): """Legacy alias of decodebytes().""" import warnings warnings.warn("decodestring() is a deprecated alias, use decodebytes()", DeprecationWarning, 2) return decodebytes(s) @@ -378,17 +384,17 @@ def main(): try: opts, args = getopt.getopt(sys.argv[1:], 'deut') except getopt.error as msg: sys.stdout = sys.stderr print(msg) print("""usage: %s [-d|-e|-u|-t] [file|-] -d, -u: decode -e: encode (default) - -t: encode and decode string 'Aladdin:open sesame'"""%sys.argv[0]) + -t: encode and decode string 'Aladdin:open sesame'""" % sys.argv[0]) sys.exit(2) func = encode for o, a in opts: if o == '-e': func = encode if o == '-d': func = decode if o == '-u': func = decode if o == '-t': test(); return if args and args[0] != '-':