Base64 is a binary-to-text encoding scheme that takes raw input bytes and encodes it in a radix-64 representation, using the characters A-Z, a-z, 0-9, and the symbols +, / and =. Base64 encoding is used when there is a need to store or transmit binary data over a system that only supports text data, without losing or corrupting said data.

Java 8 provides a Base64 class in the java.util package which can be used to encode strings into Base64, and decode Base64 strings into normal strings.

Encoding data into Base64

To encode a string into Base64, first, we convert the string into a byte array. Then, we fetch an object of the Base64.Encoder class using Base64.getEncoder(), and pass the byte array to the encodeToString() method:

String inputString = "hello world~";

byte[] inputStringBytes = inputString.getBytes();
String base64String = Base64.getEncoder().encodeToString(inputStringBytes);
System.out.println(base64String);
// prints: aGVsbG8gd29ybGR+

We can also perform the entire conversion within a single expression, as shown below:

String inputString = "hello world~";

String base64String = Base64.getEncoder().encodeToString(inputString.getBytes());
System.out.println(base64String);
// prints: aGVsbG8gd29ybGR+

Decoding data from Base64

To decode a Base64-encoded string, we use Base64.getDecoder() to fetch an object of the Base64.Decoder class, and pass the input string to its decode() method. This gives us a byte array, which can be converted to a string.

String inputString = "aGVsbG8gd29ybGR+";

byte[] base64DecodedBytes = Base64.getDecoder().decode(inputString);
String decodedString = new String(base64DecodedBytes);
System.out.println(decodedString);
// prints: hello world~

Just as before, we can perform the conversion within a single expression:

String inputString = "aGVsbG8gd29ybGR+";

String decodedString = new String(Base64.getDecoder().decode(inputString));
System.out.println(decodedString);
// prints: hello world~

URL-safe Base64 encoding

Base64 strings make use of the symbols +, /. However, these characters carry special meaning when used in the context of a filename or an URL. For example, in the context of a filename, a string such as AB/CD implies there's a folder named AB in which there's a file named CD. Java supports a URL/filename-safe Base64 encoding scheme, where the + and / characters are replaced with - and _ characters to prevent such conflicts.

We can fetch the URL-safe encoder using Base64.getUrlEncoder(). Then, we can convert our input string to Base64 using the encodeToString() method:

String inputString = "hello world~";

String base64String = Base64.getUrlEncoder().encodeToString(inputString.getBytes());
System.out.println(base64String);
// prints: aGVsbG8gd29ybGR-

Similarly, we can fetch the URL-safe decoder using Base64.getUrlDecoder() method, and we can convert a Base64-encoded string using the decode() method like so:

String inputString = "aGVsbG8gd29ybGR-";

String decodedString = new String(Base64.getUrlDecoder().decode(inputString));
System.out.println(decodedString);
// prints: hello world~

Removing padding characters from Base64 strings

When a string is converted to Base64, the padding character = is added to make the length of the output string divisible by 3. This behavior is to achieve technical compliance with the Base64 specification. However, the padding is optional and even when a Base64-encoded string does not have padding, it can be successfully decoded.

To convert a string to Base64 without padding characters, we can use the withoutPadding() method of the Base64.Encoder class, as shown below:

String inputString = "this is a string";

String base64String = Base64.getEncoder().withoutPadding().encodeToString(inputString.getBytes());
System.out.println(base64String);
// prints: dGhpcyBpcyBhIHN0cmluZw

Had we not used the withoutPadding() option, we would have got the string dGhpcyBpcyBhIHN0cmluZw== as the output.

There are no special steps required for decoding the Base64-encoded string without padding. It can be decoded using the regular Base64 decoder, like so:

String inputString = "dGhpcyBpcyBhIHN0cmluZw";

String decodedString = new String(Base64.getUrlDecoder().decode(inputString));
System.out.println(decodedString);
// prints: this is a string

MIME-compliant Base64 encoding

MIME is a specification to transmit non-ASCII data to email servers. MIME encoding is similar to Base64 encoding, however, if the Base64-encoded data has more than 76 characters, the data is split on to multiple lines, each line having a maximum of 76 characters.

To convert a string into a MIME-compliant Base64 encoding, we can fetch the MIME-compliant encoder by using Base64.getMimeEncoder(), and then pass the input string to the encodeToString() method:

String inputString = "The quick brown fox jumps over the lazy dog. " +
  "Jackdaws love my big sphinx of quartz. " +
  "Pack my box with five dozen liquor jugs.";

String base64String = Base64.getMimeEncoder().encodeToString(inputString.getBytes());
System.out.println(base64String);

The program produces the following output. Since there are 172 characters in the output, it has been split on to 3 lines.

VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4gSmFja2Rhd3MgbG92
ZSBteSBiaWcgc3BoaW54IG9mIHF1YXJ0ei4gUGFjayBteSBib3ggd2l0aCBmaXZlIGRvemVuIGxp
cXVvciBqdWdzLg==

We can decode a MIME-compliant Base64 string by fetching the MIME-compliant decoder with Base64.getMimeDecoder():

String inputString = "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4gSmFja2Rhd3MgbG92\r\n" +
  "ZSBteSBiaWcgc3BoaW54IG9mIHF1YXJ0ei4gUGFjayBteSBib3ggd2l0aCBmaXZlIGRvemVuIGxp\r\n" +
  "cXVvciBqdWdzLg==";

String decodedString = new String(Base64.getMimeDecoder().decode(inputString));
System.out.println(decodedString);

Running the program produces the original input string:

The quick brown fox jumps over the lazy dog. Jackdaws love my big sphinx of quartz. Pack my box with five dozen liquor jugs.