This project is a wrapper on libbase64.
It aims to provide a fast base64 implementation for base64 encoding/decoding.
pip install pybase64
pybase64 uses the same API as Python base64 "modern interface" (introduced in Python 2.4) for an easy integration.
To get the fastest decoding, it is recommended to use the pybase64.b64decode with validate=True (or ignorechars=b"") and padded=True when possible.
import pybase64
print(pybase64.b64encode(b'>>>foo???', altchars='_:'))
# b'Pj4_Zm9vPz8:'
print(pybase64.b64decode(b'Pj4_Zm9vPz8:', altchars='_:', validate=True))
# b'>>>foo???'
# Standard encoding helpers
print(pybase64.standard_b64encode(b'>>>foo???'))
# b'Pj4+Zm9vPz8/'
print(pybase64.standard_b64decode(b'Pj4+Zm9vPz8/'))
# b'>>>foo???'
# URL safe encoding helpers
print(pybase64.urlsafe_b64encode(b'>>>foo???'))
# b'Pj4-Zm9vPz8_'
print(pybase64.urlsafe_b64decode(b'Pj4-Zm9vPz8_'))
# b'>>>foo???'A command-line tool is also provided. It has encode, decode and benchmark subcommands.
usage: pybase64 [-h] [-V] {benchmark,encode,decode} ...
pybase64 command-line tool.
positional arguments:
{benchmark,encode,decode}
tool help
benchmark -h for usage
encode -h for usage
decode -h for usage
optional arguments:
-h, --help show this help message and exit
-V, --version show program's version number and exit
Full documentation on Read the Docs.
Running Python 3.15.0rc3, Apple clang version 21.0.0 (clang-2100.3.34.2), macOS 26.6.2, Apple M1 Max
pybase64 1.5.1 (C extension active - NEON) bench: altchars=None, validate=True, padded=True pybase64.encodebytes: 6577 MB/s (135,696 bytes -> 183,309 bytes) pybase64.b64encode: 17614 MB/s (135,696 bytes -> 180,928 bytes) pybase64.b64decode: 8975 MB/s (180,928 bytes -> 135,696 bytes) base64.encodebytes: 2342 MB/s (135,696 bytes -> 183,309 bytes) base64.b64encode: 2640 MB/s (135,696 bytes -> 180,928 bytes) base64.b64decode: 2594 MB/s (180,928 bytes -> 135,696 bytes) bench: altchars=None, validate=True, padded=False pybase64.b64encode: 17525 MB/s (135,696 bytes -> 180,928 bytes) pybase64.b64decode: 2475 MB/s (180,928 bytes -> 135,696 bytes) base64.b64encode: 2665 MB/s (135,696 bytes -> 180,928 bytes) base64.b64decode: 2604 MB/s (180,928 bytes -> 135,696 bytes) bench: altchars=None, ignorechars=b'', padded=False pybase64.b64decode: 2491 MB/s (180,928 bytes -> 135,696 bytes) base64.b64decode: 2642 MB/s (180,928 bytes -> 135,696 bytes) bench: altchars=None, ignorechars=b'\n', padded=True pybase64.b64decode: 2364 MB/s (183,308 bytes -> 135,696 bytes) base64.b64decode: 2083 MB/s (183,308 bytes -> 135,696 bytes) bench: altchars=None, ignorechars=b'\n', padded=False pybase64.b64decode: 2358 MB/s (183,308 bytes -> 135,696 bytes) base64.b64decode: 1945 MB/s (183,308 bytes -> 135,696 bytes) bench: altchars=None, validate=False, padded=True pybase64.b64decode: 2365 MB/s (183,308 bytes -> 135,696 bytes) base64.b64decode: 2033 MB/s (183,308 bytes -> 135,696 bytes) bench: altchars=None, validate=False, padded=False pybase64.b64decode: 2362 MB/s (183,308 bytes -> 135,696 bytes) base64.b64decode: 1965 MB/s (183,308 bytes -> 135,696 bytes) bench: altchars=b'-_', validate=True, padded=True pybase64.b64encode: 10779 MB/s (135,696 bytes -> 180,928 bytes) pybase64.b64decode: 6007 MB/s (180,928 bytes -> 135,696 bytes) base64.b64encode: 2659 MB/s (135,696 bytes -> 180,928 bytes) base64.b64decode: 1195 MB/s (180,928 bytes -> 135,696 bytes) bench: altchars=b'-_', validate=True, padded=False pybase64.b64encode: 10692 MB/s (135,696 bytes -> 180,928 bytes) pybase64.b64decode: 2194 MB/s (180,928 bytes -> 135,696 bytes) base64.b64encode: 2658 MB/s (135,696 bytes -> 180,928 bytes) base64.b64decode: 1196 MB/s (180,928 bytes -> 135,696 bytes) bench: altchars=b'-_', ignorechars=b'', padded=True pybase64.b64decode: 5952 MB/s (180,928 bytes -> 135,696 bytes) base64.b64decode: 2631 MB/s (180,928 bytes -> 135,696 bytes) bench: altchars=b'-_', ignorechars=b'', padded=False pybase64.b64decode: 2183 MB/s (180,928 bytes -> 135,696 bytes) base64.b64decode: 2595 MB/s (180,928 bytes -> 135,696 bytes) bench: altchars=b'-_', ignorechars=b'\n', padded=True pybase64.b64decode: 2054 MB/s (183,308 bytes -> 135,696 bytes) base64.b64decode: 2060 MB/s (183,308 bytes -> 135,696 bytes) bench: altchars=b'-_', ignorechars=b'\n', padded=False pybase64.b64decode: 2069 MB/s (183,308 bytes -> 135,696 bytes) base64.b64decode: 1937 MB/s (183,308 bytes -> 135,696 bytes) bench: altchars=b'-_', validate=False, padded=True pybase64.b64decode: 2073 MB/s (183,308 bytes -> 135,696 bytes) base64.b64decode: 1055 MB/s (183,308 bytes -> 135,696 bytes) bench: altchars=b'-_', validate=False, padded=False pybase64.b64decode: 2084 MB/s (183,308 bytes -> 135,696 bytes) base64.b64decode: 1038 MB/s (183,308 bytes -> 135,696 bytes)
- Publish PyPy 3.12 wheels
- PyPy 3.11 wheels moved from
pp311-pypy311_pp73topp311-pypy311_pp80 - Publish GraalPy 3.13 wheels
- Fix a Py_buffer Use-After-Release in error paths
- Speed-up translation on aarch64
- Fix invalid data successfully decoded when using altchars (slice ends with padding)
- Fix thread safety selecting codec
- Add
paddedandwrapcolparameters tob64encode - Add
paddedparameter tourlsafe_b64encode - Add
paddedparameter tob64decode&urlsafe_b64decode urlsafe_b64decodenow defaults topadded=Falseto align with Python 3.15 behavior- Add
ignorecharsandcanonicalparameters tob64decode - Handle excess padding with the same behavior as CPython 3.15
- Reject non-ASCII strings in
b64decodewhenvalidate=False - Deprecate accepting the
+and/characters with an alternative alphabet when decoding - Use
ValueErrorinstead ofAssertionErroron altchars length validation - Add SBOM to PyPI wheels
- Publish python 3.15 wheels
- Drop python 3.8 support
- Stop publishing python 3.13t wheels
- Publish Android Python 3.14 wheels
- Publish GraalPy v25 wheels
- Update base64 library (Windows ARM64 Neon support)
- Publish Python 3.14 wheels
- Publish Linux riscv64 wheels
- Publish Android wheels
- Publish iOS wheels
- Publish GraalPy wheels
- Publish PyPy 3.11 wheels
- Publish armv7l wheels
- Publish python 3.13 wheels
- Add support for free-threaded builds
- Add MSYS2 support for C-extension
- Better logging on base64 build failure when C-extension build is optional
- Drop python 3.6 & 3.7 support
- Update base64 library
- PyPy: fix wrong outcome with non C-contiguous buffer
- Add missing py.typed marker
- Update base64 library
- Add AVX512-VBMI implementation
- Rework extension build to remove adherence on distutils
- Publish python 3.12 wheels
- Documentation now uses furo theme
- Update base64 library
- Publish python 3.11 wheels
- Update base64 library
- Fix C extension build on musl distros
- Publish musllinux wheels
- Publish PyPy 3.8 (pypy38_pp73) wheels
- Release the GIL
- Publish CPython 3.10 wheels
- Drop python 3.5 support
- Add macOS arm64 wheel
- GitHub Actions: fix build on tag
- Add PyPy wheels
- Add aarch64, ppc64le & s390x manylinux wheels
- Move CI from TravisCI/AppVeyor to GitHub Actions
- Fix publication of Linux/macOS wheels
- Add b64encode_as_string, same as b64encode but returns a str object instead of a bytes object
- Add b64decode_as_bytearray, same as b64decode but returns a bytarray object instead of a bytes object
- Speed-Up decoding from UCS1 strings
- Update base64 library
- Publish python 3.9 wheels
- Publish python 3.8 wheels
- Drop python 3.4 support
- Drop python 2.7 support
- Publish python 3.7 wheels
- Drop python 3.3 support
- Speed-up decoding when validate==False
- Fix deployment issues
- Add encodebytes function
- Fixed invalid results on Windows
Added documentation
Added subcommands to the main script:
- help
- version
- encode
- decode
- benchmark
- Updated base64 native library
- Fixed deployment issues
- First public release