Base64 encode/decode · Guide

Base64 Encode Bytes: Byte Arrays in Python, Java, C# and JS

Base64 is defined over bytes, so encoding a byte array is the most direct use of it — no character encoding involved, nothing to get wrong. The mistakes appear when a string sneaks into the pipeline.

The straightforward case

Every language takes bytes in and gives bytes or a string out:

Python
# Python — bytes in, bytes out
import base64
encoded = base64.b64encode(data)          # bytes
decoded = base64.b64decode(encoded)       # bytes

// Java
String encoded = Base64.getEncoder().encodeToString(data);
byte[] decoded = Base64.getDecoder().decode(encoded);

// C#
string encoded = Convert.ToBase64String(data);
byte[] decoded = Convert.FromBase64String(encoded);

Python is the strict one: b64encode refuses a str outright. That refusal is a feature — it forces you to state the encoding when text is involved instead of silently picking one.

JavaScript needs a conversion

btoa operates on a binary string, not a Uint8Array, so byte arrays need converting first:

JavaScript
// Uint8Array -> Base64
const b64 = btoa(String.fromCharCode(...bytes));

// Base64 -> Uint8Array
const bytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));

The spread in String.fromCharCode(...bytes) blows the call stack on large arrays. For anything over about 100 KB, chunk it or use a FileReader with a Blob.

Keeping bytes as bytes

The classic corruption bug is a byte array converted to a string somewhere in the middle — through a text-mode file read, a JSON round trip, or a database column with a character type. Any byte that is not valid in the assumed encoding gets replaced, and the data is silently destroyed.

If bytes must pass through a text channel, that is exactly what Base64 is for: encode at the boundary, decode on the other side, and never let raw bytes touch a string type in between.

Frequently asked questions

Why does Python reject my string?

b64encode requires bytes. Call .encode() on the string first, choosing the encoding deliberately.

Why does btoa fail on a large array?

The spread operator exceeds the argument limit. Process the array in chunks.

Does encoding bytes lose information?

No. The round trip is exact — every byte comes back unchanged.

Ready to try it?

Open the free browser-based Base64 encode/decode and apply what you just read — no sign-up, runs locally.

Open the Base64 encode/decode tool