# Data : Base64 - https://datatracker.ietf.org/doc/html/rfc4648 - https://base64encode.org/ ## Overview Encodes 3 bytes (24 bits) into 4 bytes (32 bits) using a 64-character alphabet of printable characters — typically `A-Za-z0-9+/` — and using `=` to pad the resulting string to a multiple of four. In other words, every 6 bits of data is turned into an 8-bit ASCII character. The standard defines two variants: - the primary or default variant (`Base64`), which uses `+/` as the last two characters; this variant is used by MIME - the "URL- and filename-safe" variant (`Base64URL`), which uses `-_` instead. #### Base32 Same concept, but encodes every 5 bits into 8 bits using a 32-character alphabet — or in other words, converts 5 bytes into 8 bytes using `=` to pad the resulting string to a multiple of eight. Alphabet: `A-Z2-7` ## Python There is no pre-built alphabet string for either Base64 variant, but you can create one as follows: ```python import string alphabet_base64 = string.ascii_uppercase + string.ascii_lowercase + string.digits + "+/" alphabet_base64url = string.ascii_uppercase + string.ascii_lowercase + string.digits + "-_" ``` If you're dealing with inputs that include both variants of Base64 and want to normalize them to a single variant: ```python def normalize_base64( data: str ) -> str: return data.replace( "-", "+" ).replace( "_", "/" ) # convert Base64URL to Base64 ``` If you need to generate cryptographically-secure random strings of Base64: ```python import secrets def random_base64( chars: int ) -> str: padding = chars % 4 return "".join( secrets.choice( alphabet_base64 ) for i in range( chars ) ) + "=" * padding def random_base64url( chars: int ) -> str: padding = chars % 4 return "".join( secrets.choice( alphabet_base64url ) for i in range( chars ) ) + "=" * padding ``` #### base64 Package API ```python # for Base64 variant b64encode( bytes ) -> bytes # convert data (bytes) to Base64 (bytes) b64decode( str | bytes ) -> bytes # convert Base64 (str|bytes) to data (bytes) # for Base64URL variant urlsafe_b64encode( bytes ) -> bytes urlsafe_b64decode( str | bytes ) -> bytes # for Base32 b32encode( bytes ) -> bytes # convert data (bytes) to Base32 (bytes) b32decode( str | bytes ) -> bytes # convert Base32 (str|bytes) to data (bytes) # reminder - to turn str into bytes or vice-versa: mystr.encode() -> bytes mybytes.decode() -> str ```