base64.encodebytes / decodebytes
The "legacy interface" for email and PEM-style data: encodebytes breaks the output every 57 input bytes (76 characters) and ends with a newline. Both functions accept only bytes — not str.
Demo
import base64 base64.encodebytes('hi'.encode() * 1).splitlines()
57 input bytes are exactly one 76-character line; at 60 bytes a second, short line starts. The output always ends with a newline, which is why even "hi" gives one line, while empty input gives no line at all. decodebytes is the lenient decoder: like b64decode without validate, it drops characters such as * but still requires padding.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| s | bytes-like | yes | Data to encode, or Base64 bytes to decode. A str raises TypeError in both directions. |
Return value
bytes — Encode: Base64 in lines of 76 characters plus b"\n", with a trailing newline. Decode: the original bytes.
Common patterns
import base64, textwrap body = '\n'.join(textwrap.wrap(base64.b64encode(der).decode('ascii'), 64)) pem = f'-----BEGIN CERTIFICATE-----\n{body}\n-----END CERTIFICATE-----\n'
import base64 with open('report.pdf', 'rb') as f: body = base64.encodebytes(f.read()).decode('ascii')
Examples
Pitfalls
import base64 base64.encodebytes(b'user:pass').decode()
import base64 base64.b64encode(b'user:pass').decode()
import base64 base64.decodebytes('aGk=')
import base64 base64.decodebytes('aGk='.encode())
When to use
- Email (MIME) bodies and other formats limited to 76-character lines
- Decoding line-wrapped Base64 you already have as bytes
- Tokens, headers, JSON, URLs → b64encode (no newlines)
- PEM (64-character lines) → b64encode plus textwrap
- Strict validation → b64decode(s, validate=True)
Notes
FAQ
You used encodebytes (or encode), which produces MIME lines of 76 characters with a newline after each — including the last. Use b64encode for a single line without newlines.