Base64 is a binary-to-text encoding scheme that describes binary data in an ASCII string format by translating it into a radix-64 representation. It is primarily used to transfer content-based messages over the Internet.

In this article, you'll learn how to perform Base64 encoding and decoding by using the Base64 class in Java. This class provides static methods to get encoders and decoders for the Base64 encoding scheme.

Base64 Encoding Variants

The Base64 class was introduced in Java 8 and it supports the following variants of Base64 as specified in RFC 4648 and RFC 2045:

  • Basic: — This is the standard Base64 encoding that only uses a-z, A-Z, 0-9, /, and + characters (also called The Base64 Alphabet) for encoding and decoding operation. The encoder does not add the line feed character. If there are characters outside of the Base64 alphabet, the decoder rejects the data.
  • URL and Filename safe — This is very much similar to the Basic Base64 encoding except that + and / symbols are replaced with - and _ respectively to make the output URL and filename safe. No line feed character is added by the encoder. The decoder rejects the data if it contains characters outside of a-z, A-Z, 0-9, -, and _ (known as URL and Filename safe Base64 Alphabet).
  • MIME — The MIME variant uses the Basic Base64 Alphabet (characters from a-z, A-Z, 0-9, /, and +) for encoding and decoding operation. The encoded output is represented in lines of no more than 76 characters each. Every line, except the last line, is separated from the next line by using a carriage return \r followed by a linefeed \n. The decoder ignores all line separators or other characters not found in the base64 Alphabet.

Base64 Encoding in Java

Now it is a time to do the actual Base64 encoding in Java by using the Base64 class. Let us start with the basic encoding example.

Base64 Basic Encoding

The simplest way to Base64 encode a string in Java is by using the basic encoding scheme. The basic encoder keeps the things simple — no line feeds are added to the output and the output is mapped to a set of characters in the Base64 Alphabet (a-zA-Z0-9+/).

The getEncoder() method returns the Base64.Encoder class instance that encodes using the Basic type Base64 encoding scheme. Here is an example that shows how to perform basic Base64 encoding in Java:

try {
    // data to encode
    String data = "This is an example string.";

    // Base64 encode the string
    String encodedStr = Base64.getEncoder()
            .encodeToString(data.getBytes(StandardCharsets.UTF_8.name()));

    // print the output
    System.out.println(encodedStr);

} catch (UnsupportedEncodingException ex) {
    ex.printStackTrace();
}

You will see the following output:

VGhpcyBpcyBhbiBleGFtcGxlIHN0cmluZy4=

Base64 Basic Encoding without Padding

By default, the length of the Base64 encoded string must be a multiple of three. If it is not, the encoder adds one or two padding characters (=) at the end of the encoded string. While decoding, these padding characters are discarded.

It is always recommended to use the padding if you want to decode the string at a later point. But if you are sure that the encoded data will never be decoded, you can skip the padding with withoutPadding() and save a couple of bytes:

try {
    // data to encode
    String data = "This is an example string.";

    // Base64 encode the string without padding
    String encodedStr = Base64.getEncoder()
            .withoutPadding()
            .encodeToString(data.getBytes(StandardCharsets.UTF_8.name()));

    // print the output
    System.out.println(encodedStr);

} catch (UnsupportedEncodingException ex) {
    ex.printStackTrace();
}

Here is the output without any extra padding:

VGhpcyBpcyBhbiBleGFtcGxlIHN0cmluZy4

Base64 URL and Filename Safe Encoding

The URL and filename safe Base64 encoding is same as the basic Base64 encoding with the exception that + and / characters are replaced with the URL safe characters - and _ in the final output.

This encoding variant is particularly useful when you want to include the encoded string to the URL or filename. It uses the URL and filename safe Base64 alphabet (a-zA-Z0-9-_) and does not add any line separation.

Just call the getUrlEncoder() method to get a Base64.Encoder instance that encodes using the URL and Filename safe type Base64 encoding scheme:

try {
    // url to encode
    String data = "Are you a web developer?";

    // Base64 url and filename safe encoding
    String encodedStr = Base64.getUrlEncoder()
            .encodeToString(data.getBytes(StandardCharsets.UTF_8.name()));

    // print the output
    System.out.println(encodedStr);

} catch (UnsupportedEncodingException ex) {
    ex.printStackTrace();
}

Here is the output:

QXJlIHlvdSBhIHdlYiBkZXZlbG9wZXI_

Important: Don't confuse URL and filename safe Base64 encoding with the URL string encoding. URL string encoding converts a string into a valid URL format only without changing the characters to random ASCII symbols. Whereas URL and filename safe encoding is actually a Base64 encoding with the exception that it only uses URL friendly symbols.

Base64 MIME Encoding

The MIME encoder creates a Base64 encoded string by using the basic alphabet (a-zA-Z0-9+/) but in a MIME friendly format. Each line of the output is no more than 76 characters and ends with a carriage return followed by a linefeed (\r\n).

You can use the getMimeEncoder() method to get a Base64.Encoder instance that encodes using the MIME type Base64 encoding scheme:

try {
    // create a block of text to encode
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < 10; i++) {
        builder.append(UUID.randomUUID().toString());
    }

    // Base64 MIME encoding
    String encodedStr = Base64.getMimeEncoder()
            .encodeToString(builder.toString().getBytes(StandardCharsets.UTF_8.name()));

    // print the output
    System.out.println(encodedStr);

} catch (UnsupportedEncodingException ex) {
    ex.printStackTrace();
}

Following is the MIME encoding output:

NmQ2MWIyNTItOGYwYi00MjM1LWE0ZjItOGU3OWRhYzQyNzhmYzQ4NjRiNGUtYzdmYS00MTI3LTlh
NDEtNmIwNTlhODNkZWU1MWE3NWYyOGItZmQyMC00NzkwLTkxMDQtODA2MGNlYjJkNGM0YTBiZDlm
ZDktZDk4Ni00YzM0LTg4OGQtMzBkNjk1ODJmMjRmNDViNjBmNjEtNDkzMy00MzFhLTk2YTItMTdh
YmExMWY4Y2NkMjBkNmQxNTctYzFmOS00MWE3LTk5NTEtNmFiYTRlMjQ4NDYzYzU3NzNlZDYtZTg2
MC00ZWRmLWI4YWQtMDhlYWY2ZjZkMTgwZDNlODRjMzktYzlhMy00OTMyLWFmZGItMjZkOWQzYTFj
M2FjZTRhOWJmYmQtZTcxNC00MjBkLTkwYmEtODFmMzE3ZTU3MjdiNTE3ZDRhZTItNGIzNi00YTIx
LWFlMWMtNmZiOWZjMzIxOTU4

Base64 Decoding in Java

For every Base64 encoding variant implemented by the Base64 class, there is a decoder to turn the data back to its original form (except without padding encoding).

Base64 Basic Decoding

For Base64 basic decoding, just use the getDecoder() to get a Base64.Decoder instance that decodes using the Basic type Base64 encoding scheme:

try {
    // data to decode
    String encodedData = "VGhpcyBpcyBhbiBleGFtcGxlIHN0cmluZy4=";

    // Base64 basic decoding
    byte[] dataBytes = Base64.getDecoder().decode(encodedData);
    String data = new String(dataBytes, StandardCharsets.UTF_8.name());
    
    // print the output
    System.out.println(data);

} catch (UnsupportedEncodingException ex) {
    ex.printStackTrace();
}

Here is the original string after decoding:

This is an example string.

Base64 URL and Filename Safe Decoding

For Base64 URL and filename safe decoding, there is a getUrlDecoder() static method that returns a Base64.Decoder instance to decode by using the URL and Filename safe type Base64 encoding scheme:

try {
    // data to decode
    String encodedData = "QXJlIHlvdSBhIHdlYiBkZXZlbG9wZXI_";

    // Base64 URL and filename safe decoding
    byte[] dataBytes = Base64.getUrlDecoder().decode(encodedData);
    String data = new String(dataBytes, StandardCharsets.UTF_8.name());

    // print the output
    System.out.println(data);

} catch (UnsupportedEncodingException ex) {
    ex.printStackTrace();
}

Here is the output:

Are you a web developer?

Base64 MIME Decoding

The getMimeDecoder() utility method returns a Base64.Decoder that decodes using the MIME type Base64 decoding scheme:

try {
    // data to decode
    String encodedData = "MzcwNDkwZjUtNDk1Ni00YTg1LWJkZjItZWQzNTU2MDI0MjcxCmY2OGMzZWVhLTFhNDItNDkyZC1h\n" +
            "MzdlLWRjMjJlODk5YjllNAo1YWMzMjExMy0yOWZmLTRhYWYtYmUyYy0zOWVhYjg5YWY4OTMKNzQ3\n" +
            "ZDE5NTctY2ZhNS00MDcxLTllYjktMjAzMDFkODBhYzc0Cg==";

    // Base64 MIME decoding
    byte[] dataBytes = Base64.getMimeDecoder().decode(encodedData);
    String data = new String(dataBytes, StandardCharsets.UTF_8.name());

    // print the output
    System.out.println(data);

} catch (UnsupportedEncodingException ex) {
    ex.printStackTrace();
}

Here is the original data that was encoded by using the MIME encoding:

370490f5-4956-4a85-bdf2-ed3556024271
f68c3eea-1a42-492d-a37e-dc22e899b9e4
5ac32113-29ff-4aaf-be2c-39eab89af893
747d1957-cfa5-4071-9eb9-20301d80ac74

Base64 Encoding and Decoding using Apache Commons Codec

The Apache Commons Codec library provides common encoders and decoders such as Base64, Hex, Phonetic and URLs.

To add Commons Codec to your project, add the following dependency to your build.gradle file:

implementation 'commons-codec:commons-codec:1.13'

If you are using Maven, add the following dependency to your pom.xml file:

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.13</version>
</dependency>

Similar to Java 8, Commons Codec provides the Base64 class for Base64 encoding and decoding as defined by RFC 2045.

Let us use this class to Base64 encode a string in Java:

try {
    // data to encode
    String data = "Java programming language.";

    // create a new instance of Base64 (Commons Codec)
    Base64 base64 = new Base64();

    // Base64 encode
    byte[] encodedBytes = base64.encode(data.getBytes());
    String encodedStr = new String(encodedBytes, StandardCharsets.UTF_8.name());

    // print the output
    System.out.println(encodedStr);
    // SmF2YSBwcm9ncmFtbWluZyBsYW5ndWFnZS4=

} catch (Exception ex) {
    ex.printStackTrace();
}

If you do not want to create an instance of Base64, use the static method Base64.encodeBase64() instead:

try {
    // data to encode
    String data = "Java programming language.";

    // Base64 encode
    String encodedStr = new String(Base64.encodeBase64(data.getBytes()), StandardCharsets.UTF_8.name());

    // print the output
    System.out.println(encodedStr);

} catch (Exception ex) {
    ex.printStackTrace();
}

Similarly, you can decode the encoded string by using the Base64.decodeBase64() static method:

try {
    // data to decode
    String encodedSData = "SmF2YSBwcm9ncmFtbWluZyBsYW5ndWFnZS4=";

    // Base64 decode
    String data = new String(Base64.decodeBase64(encodedSData), StandardCharsets.UTF_8.name());

    // print the output
    System.out.println(data);

} catch (Exception ex) {
    ex.printStackTrace();
}

✌️ Like this article? Follow @attacomsian on Twitter. You can also follow me on LinkedIn and DEV. Buy me a coffee (cost $3)

Need help to start a new Spring Boot or MEAN stack project? I am available for contract work. Hire me to accomplish your business goals with engineering and design. Let’s talk about your project: hi@attacomsian.com.