OLD | NEW |
(Empty) | |
| 1 # Copyright (C) 2002-2007 Python Software Foundation |
| 2 # Author: Ben Gertzfield |
| 3 # Contact: email-sig@python.org |
| 4 |
| 5 """Base64 content transfer encoding per RFCs 2045-2047. |
| 6 |
| 7 This module handles the content transfer encoding method defined in RFC 2045 |
| 8 to encode arbitrary 8-bit data using the three 8-bit bytes in four 7-bit |
| 9 characters encoding known as Base64. |
| 10 |
| 11 It is used in the MIME standards for email to attach images, audio, and text |
| 12 using some 8-bit character sets to messages. |
| 13 |
| 14 This module provides an interface to encode and decode both headers and bodies |
| 15 with Base64 encoding. |
| 16 |
| 17 RFC 2045 defines a method for including character set information in an |
| 18 `encoded-word' in a header. This method is commonly used for 8-bit real names |
| 19 in To:, From:, Cc:, etc. fields, as well as Subject: lines. |
| 20 |
| 21 This module does not do the line wrapping or end-of-line character conversion |
| 22 necessary for proper internationalized headers; it only does dumb encoding and |
| 23 decoding. To deal with the various line wrapping issues, use the email.header |
| 24 module. |
| 25 """ |
| 26 from __future__ import unicode_literals |
| 27 from __future__ import division |
| 28 from __future__ import absolute_import |
| 29 from future.builtins import range |
| 30 from future.builtins import bytes |
| 31 |
| 32 __all__ = [ |
| 33 'body_decode', |
| 34 'body_encode', |
| 35 'decode', |
| 36 'decodestring', |
| 37 'header_encode', |
| 38 'header_length', |
| 39 ] |
| 40 |
| 41 |
| 42 from base64 import b64encode |
| 43 from binascii import b2a_base64, a2b_base64 |
| 44 |
| 45 CRLF = '\r\n' |
| 46 NL = '\n' |
| 47 EMPTYSTRING = '' |
| 48 |
| 49 # See also Charset.py |
| 50 MISC_LEN = 7 |
| 51 |
| 52 |
| 53 # Helpers |
| 54 def header_length(bytearray): |
| 55 """Return the length of s when it is encoded with base64.""" |
| 56 groups_of_3, leftover = divmod(len(bytearray), 3) |
| 57 # 4 bytes out for each 3 bytes (or nonzero fraction thereof) in. |
| 58 n = groups_of_3 * 4 |
| 59 if leftover: |
| 60 n += 4 |
| 61 return n |
| 62 |
| 63 |
| 64 def header_encode(header_bytes, charset='iso-8859-1'): |
| 65 """Encode a single header line with Base64 encoding in a given charset. |
| 66 |
| 67 charset names the character set to use to encode the header. It defaults |
| 68 to iso-8859-1. Base64 encoding is defined in RFC 2045. |
| 69 """ |
| 70 if not header_bytes: |
| 71 return "" |
| 72 if isinstance(header_bytes, str): |
| 73 header_bytes = header_bytes.encode(charset) |
| 74 encoded = b64encode(header_bytes).decode("ascii") |
| 75 return '=?%s?b?%s?=' % (charset, encoded) |
| 76 |
| 77 |
| 78 def body_encode(s, maxlinelen=76, eol=NL): |
| 79 r"""Encode a string with base64. |
| 80 |
| 81 Each line will be wrapped at, at most, maxlinelen characters (defaults to |
| 82 76 characters). |
| 83 |
| 84 Each line of encoded text will end with eol, which defaults to "\n". Set |
| 85 this to "\r\n" if you will be using the result of this function directly |
| 86 in an email. |
| 87 """ |
| 88 if not s: |
| 89 return s |
| 90 |
| 91 encvec = [] |
| 92 max_unencoded = maxlinelen * 3 // 4 |
| 93 for i in range(0, len(s), max_unencoded): |
| 94 # BAW: should encode() inherit b2a_base64()'s dubious behavior in |
| 95 # adding a newline to the encoded string? |
| 96 enc = b2a_base64(s[i:i + max_unencoded]).decode("ascii") |
| 97 if enc.endswith(NL) and eol != NL: |
| 98 enc = enc[:-1] + eol |
| 99 encvec.append(enc) |
| 100 return EMPTYSTRING.join(encvec) |
| 101 |
| 102 |
| 103 def decode(string): |
| 104 """Decode a raw base64 string, returning a bytes object. |
| 105 |
| 106 This function does not parse a full MIME header value encoded with |
| 107 base64 (like =?iso-8895-1?b?bmloISBuaWgh?=) -- please use the high |
| 108 level email.header class for that functionality. |
| 109 """ |
| 110 if not string: |
| 111 return bytes() |
| 112 elif isinstance(string, str): |
| 113 return a2b_base64(string.encode('raw-unicode-escape')) |
| 114 else: |
| 115 return a2b_base64(string) |
| 116 |
| 117 |
| 118 # For convenience and backwards compatibility w/ standard base64 module |
| 119 body_decode = decode |
| 120 decodestring = decode |
OLD | NEW |