◐ Shell
clean mode source ↗

gh-101178: Add Ascii85, Base85, and Z85 support to binascii by kangtastic · Pull Request #102753 · python/cpython

@kangtastic kangtastic changed the title Add Ascii85 and base85 support to binascii gh-101178: Add Ascii85 and base85 support to binascii

Mar 16, 2023
Add Ascii85, base85, and Z85 encoders and decoders to `binascii`,
replacing the existing pure Python implementations in `base64`.

No API or documentation changes are necessary with respect to
`base64.a85encode()`, `b85encode()`, etc., and all existing unit
tests for those functions continue to pass without modification.

Note that attempting to decode Ascii85 or base85 data of length 1 mod 5
(after accounting for Ascii85 quirks) now produces an error, as no
encoder would emit such data. This should be the only significant
externally visible difference compared to the old implementation.

Resolves: pythongh-101178

@kangtastic kangtastic changed the title gh-101178: Add Ascii85 and base85 support to binascii gh-101178: Add Ascii85. base85, and Z85 support to binascii

Apr 21, 2025

@kangtastic kangtastic changed the title gh-101178: Add Ascii85. base85, and Z85 support to binascii gh-101178: Add Ascii85, base85, and Z85 support to binascii

Apr 21, 2025

AA-Turner

If we were strictly following PEP-0399, _base64 would be a C
module for accelerated functions in base64. Due to historical
reasons, those should actually go in binascii instead.

We still want to preserve the existing Python code in base64.
Parting out facilities for accessing the C functions into a
module named _base64 shouldn't risk a naming conflict and
will simplify testing.
This is done differently to PEP-0399 to minimize the number of
changed lines.
As we're now keeping the existing Python base 85 functions, the C
implementations should behave exactly the same, down to exception
type and wording. It is also no longer an error to try to decode
data of length 1 mod 5.

@kangtastic

AA-Turner

AA-Turner

AA-Turner

Importing update_wrapper() from functools to copy attributes
is expensive. Do it ourselves for only the most relevant ones.
This requires some code duplication, but oh well.
Using a decorator complicates function signature introspection.
Do we really need to test the legacy API twice?
Include an integer overflow check for Ascii85.
Performance gains of up to 8% for a2b_ascii85() and 25% for a2b_base85()
and a2b_z85() were observed.

serhiy-storchaka

thunder-coding pushed a commit to thunder-coding/cpython that referenced this pull request

Feb 15, 2026
…thonGH-102753)

Add Ascii85, Base85, and Z85 encoders and decoders to binascii,
replacing the existing pure Python implementations in base64.

This makes the codecs two orders of magnitude faster and consume
two orders of magnitude less memory.

Note that attempting to decode Ascii85 or Base85 data of length 1 mod 5
(after accounting for Ascii85 quirks) now produces an error, as no
encoder would emit such data. This should be the only significant
externally visible difference compared to the old implementation.

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>

ljfp pushed a commit to ljfp/cpython that referenced this pull request

Apr 25, 2026
…thonGH-102753)

Add Ascii85, Base85, and Z85 encoders and decoders to binascii,
replacing the existing pure Python implementations in base64.

This makes the codecs two orders of magnitude faster and consume
two orders of magnitude less memory.

Note that attempting to decode Ascii85 or Base85 data of length 1 mod 5
(after accounting for Ascii85 quirks) now produces an error, as no
encoder would emit such data. This should be the only significant
externally visible difference compared to the old implementation.

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>