JavaScript: btoa, atob, and Their Limitations

btoa(str) encodes a string; atob(str) decodes it. The critical limitation: btoa only works with 'binary strings' — strings where every character's code point is 0-255. For true binary data (ArrayBuffer, Uint8Array), convert to a binary string first. For Unicode strings with high code points, btoa throws — use TextEncoder to convert to UTF-8 bytes first.

Python: The base64 Module

Python's base64 module is clear and complete: base64.b64encode(bytes_obj) returns bytes; b64decode(str_or_bytes) returns bytes. URL-safe variants use urlsafe_b64encode and urlsafe_b64decode. Always encode bytes, not strings — call str.encode('utf-8') first.

Cross-Language Interoperability

Base64 is a standard, so encoded data from one language decodes correctly in another — as long as you use the same variant (standard vs URL-safe) and handle padding consistently. The most common interoperability bug is URL-safe Base64 produced by one language decoded with a standard decoder in another.

Common Encoding Pitfalls

Double-encoding (encoding an already-encoded string) produces garbage output. Missing character set normalization when encoding text strings corrupts multi-byte characters. Always track where encoding happens and where decoding happens in your data flow to prevent these issues.

Key Takeaway

Base64 APIs are consistent across languages in concept but differ in handling binary vs string input, URL-safe variants, and padding normalization. Always handle these explicitly rather than assuming defaults.