# Base64 Encoding and Decoding in Java

By Atta Ur Rehman Shah (https://attacomsian.com/about). Published Sep 28, 2019, updated Feb 26, 2020. Topics: Java.
Canonical URL: https://attacomsian.com/blog/base64-encode-decode-java

> Learn how to Base64 encode or decode a string by using Java 8 and Apache Commons Codec.

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](https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html) 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](http://www.ietf.org/rfc/rfc4648.txt) and [RFC 2045](http://www.ietf.org/rfc/rfc2045.txt):

* **Basic:** &mdash; 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** &mdash; 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** &mdash; 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 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 &mdash; 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:

```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:

```plaintext
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:

```java
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:

```plaintext
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:

```java
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:

```plaintext
QXJlIHlvdSBhIHdlYiBkZXZlbG9wZXI_
```

> **Important:** Don't confuse URL and filename safe Base64 encoding with the [URL string encoding](https://attacomsian.com/blog/encode-decode-url-string-java). 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:

```java
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:

```plaintext
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:

```java
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:

```plaintext
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:

```java
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:

```plaintext
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:

```java
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:

```plaintext
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](https://commons.apache.org/proper/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:

```groovy
implementation 'commons-codec:commons-codec:1.13'
```

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

```xml
<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](http://www.ietf.org/rfc/rfc2045.txt).

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

```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:

```java
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:

```java
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();
}
```
