ZetCode

Java Base64

Last modified: July 16, 2026

This Java Base64 tutorial shows how to encode and decode strings and binary data using the java.util.Base64 class. We cover basic encoding and decoding, URL-safe encoding, MIME encoding, wrapping streams, and working with byte buffers.

Base64

Base64 is a binary-to-text encoding scheme that represents binary data in an ASCII string format by translating it into a radix-64 representation. It is defined in RFC 4648. Each Base64 digit represents exactly six bits of data, so three bytes (24 bits) can be represented using four Base64 characters.

Base64 is widely used in applications where binary data must be transmitted over media designed to handle textual data. Common use cases include embedding images or files in HTML and CSS files, encoding attachments in email via MIME, storing binary data in JSON or XML, and transmitting credentials in HTTP headers (Basic authentication).

The following is the Base64 alphabet as defined by RFC 4648. Each character represents a six-bit value, ranging from 0 to 63.

Value Encoding Value Encoding Value Encoding Value Encoding
0A16Q32g48w
1B17R33h49x
2C18S34i50y
3D19T35j51z
4E20U36k520
5F21V37l531
6G22W38m542
7H23X39n553
8I24Y40o564
9J25Z41p575
10K26a42q586
11L27b43r597
12M28c44s608
13N29d45t619
14O30e46u62+
15P31f47v63/
Padding: =

The Java Base64 class provides three types of encoders, each designed for a specific use case. Choosing the right encoder depends on the context in which the encoded data will be used. The following table summarises the available encoder types and their characteristics.

Encoder Type Method Description
Basic Base64.getEncoder() Uses the standard Base64 alphabet. Appends padding with = characters.
URL Base64.getUrlEncoder() Uses URL-safe alphabet: replaces + and / with - and _.
MIME Base64.getMimeEncoder() Produces lines of 76 characters with \r\n line separators.

Basic encoding and decoding

The Base64.getEncoder() and Base64.getDecoder() methods provide basic encoding and decoding using the standard Base64 alphabet.

Main.java
import java.util.Base64;

void main() {

    String text = "Hello, Java!";

    String encoded = Base64.getEncoder().encodeToString(text.getBytes());
    System.out.println(encoded);

    byte[] decoded = Base64.getDecoder().decode(encoded);
    System.out.println(new String(decoded));
}

The example encodes a simple text string to Base64 and decodes it back.

String encoded = Base64.getEncoder().encodeToString(text.getBytes());

The encodeToString method converts the input byte array to a Base64-encoded string. The getBytes method converts the string to a byte array.

byte[] decoded = Base64.getDecoder().decode(encoded);

The decode method decodes a Base64-encoded string back into a byte array, which is then converted back to a string.

$ java Main.java
SGVsbG8sIEphdmEh
Hello, Java!

Encoding byte arrays

The encode method returns the encoded bytes rather than a string.

Main.java
import java.util.Base64;

void main() {

    byte[] data = {0x48, 0x65, 0x6C, 0x6C, 0x6F};

    byte[] encoded = Base64.getEncoder().encode(data);
    System.out.println(new String(encoded));

    byte[] decoded = Base64.getDecoder().decode(encoded);
    System.out.println(new String(decoded));
}

In this example, we encode a raw byte array and decode the result. The output is the same whether we use encode or encodeToString.

$ java Main.java
SGVsbG8=
Hello

Encoding emojis

Base64 encoding works with any binary data, including multi-byte Unicode characters such as emojis. The encoder processes the underlying UTF-8 bytes, not the characters themselves.

Main.java
import java.util.Base64;

void main() {

    String text = "one \uD83D\uDC18 and three \uD83D\uDC0B";
    System.out.println(text);

    String encoded = Base64.getEncoder().encodeToString(text.getBytes());
    System.out.println(encoded);

    byte[] decoded = Base64.getDecoder().decode(encoded);
    System.out.println(new String(decoded));
}

We encode a string containing an elephant emoji and a whale emoji.

String text = "one \uD83D\uDC18 and three \uD83D\uDC0B";

The string contains Unicode emoji characters. In Java source code, we can represent them with surrogate pairs (as above) or directly as emoji characters if the editor supports UTF-8.

$ java Main.java
one 🐘 and three 🐋
b25lIPCfkJggYW5kIHRocmVlIPCfkIs=
one 🐘 and three 🐋

URL-safe encoding

The standard Base64 alphabet includes + and / characters, which have special meaning in URL path segments and query strings. The URL-safe encoder replaces these with - and _ respectively, and omits padding characters.

Main.java
import java.util.Base64;

void main() {

    String text = "Hello, Java!";

    String encoded = Base64.getUrlEncoder().encodeToString(text.getBytes());
    System.out.println(encoded);

    byte[] decoded = Base64.getUrlDecoder().decode(encoded);
    System.out.println(new String(decoded));
}

The example uses the URL-safe encoder and decoder.

$ java Main.java
SGVsbG8sIEphdmEh
Hello, Java!

For this particular text, the output is the same as basic encoding because the byte values do not produce the + or / characters. When data does include those bytes, the URL-safe encoder substitutes them automatically.

MIME encoding

The MIME encoder formats long Base64 output into lines of 76 characters, separated by \r\n carriage return and line feed characters, as specified in the MIME standard. This is useful for encoding email attachments or large blocks of data.

Main.java
import java.util.Base64;

void main() {

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 100; i++) {
        sb.append("Java ");
    }

    String text = sb.toString();

    String encoded = Base64.getMimeEncoder().encodeToString(text.getBytes());
    System.out.println(encoded);

    byte[] decoded = Base64.getMimeDecoder().decode(encoded);
    System.out.println(new String(decoded));
}

We create a long string containing 100 repetitions of "Java " and encode it with the MIME encoder. The output is wrapped to 76 characters per line.

$ java Main.java
SmF2YSBKYXZhIEphdmEgSmF2YSBKYXZhIEphdmEgSmF2YSBKYXZhIEphdmEgSmF2YSBKYXZhIEphdmEg
SmF2YSBKYXZhIEphdmEgSmF2YSBKYXZhIEphdmEgSmF2YSBKYXZhIEphdmEgSmF2YSBKYXZhIEphdmEg
SmF2YSBKYXZhIEphdmEgSmF2YSBKYXZhIEphdmEgSmF2YSBKYXZhIEphdmEgSmF2YSBKYXZhIEphdmEg
SmF2YSBKYXZhIEphdmEgSmF2YSBKYXZhIEphdmEgSmF2YSBKYXZhIEphdmEgSmF2YSBKYXZhIEphdmEg
SmF2YSBKYXZh
Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java
Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java
Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java
Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java
Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java Java
Java Java Java Java Java Java Java Java Java Java

Custom MIME encoder

The getMimeEncoder method has an overloaded variant that accepts a custom line length and line separator. This allows fine-grained control over the output formatting.

Main.java
import java.util.Base64;

void main() {

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 50; i++) {
        sb.append("Java ");
    }

    String text = sb.toString();

    // Custom line length of 50 and custom separator "\n"
    String encoded = Base64.getMimeEncoder(50, "\n".getBytes())
            .encodeToString(text.getBytes());

    System.out.println(encoded);
}

The example encodes a long string with a MIME encoder configured to use a line length of 50 characters and a Unix-style newline separator instead of the default \r\n.

$ java Main.java
SmF2YSBKYXZhIEphdmEgSmF2YSBKYXZhIEphdmEgSmF2
YSBKYXZhIEphdmEgSmF2YSBKYXZhIEphdmEgSmF2YSBK
YXZhIEphdmEgSmF2YSBKYXZhIEphdmEgSmF2YSBKYXZh

Encoding with padding control

The withoutPadding method returns an encoder that omits the padding characters (=) from the output. This is useful when the encoded length is known or padding is not required.

Main.java
import java.util.Base64;

void main() {

    String text = "Java";

    String encoded = Base64.getEncoder()
            .withoutPadding()
            .encodeToString(text.getBytes());

    System.out.println(encoded);
}

The example encodes "Java" and removes the trailing padding characters.

$ java Main.java
SmF2YQ

With padding, the encoded output would be SmF2YQ==. The withoutPadding method removes the == suffix.

Encoding with stream wrapping

The Base64 class provides wrap methods that return wrapped input or output streams, enabling encoding or decoding of streaming data. This is efficient for large data sets that should not be held entirely in memory.

Main.java
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Base64;

void main() throws Exception {

    String text = "Hello, Java!";

    // Encoding via OutputStream
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    var encoderStream = Base64.getEncoder().wrap(bos);
    encoderStream.write(text.getBytes());
    encoderStream.close();

    String encoded = bos.toString();
    System.out.println(encoded);

    // Decoding via InputStream
    InputStream is = new ByteArrayInputStream(encoded.getBytes());
    var decoderStream = Base64.getDecoder().wrap(is);

    byte[] decoded = decoderStream.readAllBytes();
    System.out.println(new String(decoded));
}

The example uses the wrap method to encode data written to an output stream and decode data read from an input stream.

var encoderStream = Base64.getEncoder().wrap(bos);

wrap wraps a ByteArrayOutputStream in a Base64.OutputStream that encodes any data written to it.

var decoderStream = Base64.getDecoder().wrap(is);

wrap wraps a ByteArrayInputStream in a Base64.InputStream that decodes data as it is read.

$ java Main.java
SGVsbG8sIEphdmEh
Hello, Java!

Encoding images

A common practical use of Base64 is embedding binary image data directly into HTML or CSS files. The following example reads an image file and encodes it in Base64 format.

Main.java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;

void main() throws IOException {

    byte[] imageBytes = Files.readAllBytes(Path.of("image.png"));

    String encoded = Base64.getEncoder().encodeToString(imageBytes);

    System.out.println("data:image/png;base64," + encoded);
}

The example reads a PNG image into a byte array, encodes it with Base64, and prints a data URI suitable for embedding in an <img> tag.

byte[] imageBytes = Files.readAllBytes(Path.of("image.png"));

Files.readAllBytes reads the entire image file into a byte array.

System.out.println("data:image/png;base64," + encoded);

The encoded data is prefixed with the data URI scheme, which browsers recognize and can render directly.

Encoding with ByteBuffer

The encode and decode methods also accept ByteBuffer instances, making it convenient to work with Java NIO buffers.

Main.java
import java.nio.ByteBuffer;
import java.util.Base64;

void main() {

    String text = "Hello, Java!";

    ByteBuffer src = ByteBuffer.wrap(text.getBytes());
    ByteBuffer encoded = Base64.getEncoder().encode(src);

    System.out.println(new String(encoded.array()));

    encoded.rewind();
    ByteBuffer decoded = Base64.getDecoder().decode(encoded);
    System.out.println(new String(decoded.array()));
}

In this example, we encode and decode data using ByteBuffer objects rather than byte arrays.

$ java Main.java
SGVsbG8sIEphdmEh
Hello, Java!

Source

Java Base64 - Language Reference

In this article, we have used the Java Base64 class to encode and decode data.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than eight years of experience in teaching programming.

View all Java tutorials.