I want to compactly encode a large unsigned or signed integer having an arbitrary number of bits into a base64, base32, or base16 (hexadecimal) representation. The output will ultimately be used as a string which will be used as a filename, but this should be beside the point. I am using the latest Python 3.
This works but is far from compact:
>>> import base64, sys
>>> i: int = 2**62 - 3 # Can be signed or unsigned.
>>> b64: bytes = base64.b64encode(str(i).encode()) # Not a compact encoding.
>>> len(b64), sys.getsizeof(b64)
(28, 61)
There is a prior question, now closed, the answers for which strictly concern with an inefficient representations. Note again that we don't want to use any strings or needlessly long sequences of bytes in this exercise. As such, this question is not a duplicate of that question.
This answer is motivated in part by disparate comments by Erik A., such as for this answer. The integer is first compactly converted to bytes, following which the bytes are encoded to a variable base.
Refer to the included tests for usage examples.
If using the output as a filename, initializing the encoder with the encoding
'urlsafe_b64'
or even'b16'
are safer choices.Usage examples: