Java 8 Base64 Encoding Example
This article is about encoding Strings using Java. Until now, this was only possible by using external libraries, since Java update 8, encoding and decoding is part of the standard JRE.
In old Java versions, it was needed to use external libraries like commons-codec
or sum.misc.BASE64Decoder
for encoding and decoding Strings. Now, the package java.util
already contains a couple of classes that support this:
Basically, these util classes offer a set of static methods with encoding and decoding support in the following modes:
- Basic encoding: Uses for encoding/decoding the Base64 Alphabet as listed in the RFC 4648 and 2045.
- URL based encoding: Uses the alphabet for URL and Filenames specified in the RFC 4648.
- MIME type encoding: Uses the alphabet for encoding and decoding specified in the RFC 2045 and adds line separations.
At the end of this article you can download all the examples and snippets (and more). All code has been implemented using Java 8 update 11 and Eclipse Luna version 4.4.
In the next chapters we are going to explain how to use the different kinds of encoders and decoders:
Basic
The basic encoder does not add any line separation and encodes using the Base64 alphabet as explained before. In order to encode a given String we can write:
String str = "this is an string"; String strEncoded = Base64.getEncoder().encodeToString( str.getBytes( "utf-8" ) );
If we print the string strEncoded
out we would get:
dGhpcyBpcyBhbiBzdHJpbmc=
In order to decode this one, we can do something like:
byte[] decodedStr = Base64.getDecoder().decode( strEncoded ); System.out.println( "Decoded using basic decoding " + new String( decodedStr, "utf-8" ) );
Output would be:
Decoded using basic decoding this is an string
The basic decoder rejects (and throws and IllegalArgumentException) data that contains characters that are not contained in the base64 alphabet like ö, ä or ñ. We can see an example (again, is just an example, no practical use):
String str = "España va muy bien and German uses ö, ä and ü"; byte[] decodedStr = Base64.getDecoder().decode( str );
Output:
Exception in thread "main" java.lang.IllegalArgumentException: Illegal base64 character -f at java.util.Base64$Decoder.decode0(Unknown Source) at java.util.Base64$Decoder.decode(Unknown Source) at java.util.Base64$Decoder.decode(Unknown Source) at com.danibuiza.javacodegeeks.base64.Base64Examples.basicRejects(Base64Examples.java:97) at com.danibuiza.javacodegeeks.base64.Base64Examples.main(Base64Examples.java:20)
URL
This one is very similar to the basic encoder. It uses the URL and Filename safe base64 alphabet and does not add any line separation. This alphabet does not use special characters used in URLs like ‘/’. Here is an example:
String url = "subjects?mathematics"; String urlEncoded = Base64.getUrlEncoder().encodeToString( url.getBytes( "utf-8" ) ); //output would be: c3ViamVjdHM_bWF0aGVtYXRpY3M= String urlEncodedBasic = Base64.getEncoder().encodeToString( url.getBytes( "utf-8" ) ); //output would be: c3ViamVjdHM/bWF0aGVtYXRpY3M=
We can see that using the URL encoder we do not have any problem while using these strings in an URL, using the basic one, we do because it contains characters like ‘/’.
The decoder rejects data with characters outside the base64 url alphabet like the Basic one.
MIME
The MIME encoding uses the base64 alphabet as well for encoding and inserts line separators using a ‘\r’ followed by a ‘\n’ (return
+ end of line). It does not insert a line separator at the end of the output if not needed. Lines have 76 characters. Here is how to use it:
String encodedBuffer = Base64.getMimeEncoder().encodeToString( buffer.toString().getBytes( "utf-8" ) );
The output for the given buffer (please see download section) would be:
MzIuMTU4MjQ2NDM5NjA1NzE3LjE3MjU2OTMwNzA1ODA1MjM0Ljg1MDk4Nzg4MjQzMzE3NDE3LjQy MTczNTcwNTk1MjIxMjUyLjE5MDg4NDMzMjQ5NjcxNTY0LjQwNTc1NTMyODk5ODk5NC42MjY0ODA4 MzYzNDk5Mzc0LjMwODM1OTYyNTQ1MzczNzUuNDgxMTg0MjMyMDE3NTg5OC45MDUzMzcxNzk5OTY2 OTM1LjA1MzM1OTM0NDAxMTU3NTguNTQ4ODI4MTkyODYzMzI2OTUuOTQwNjg2NTU4NTU0ODI3LjE1 ODk3MjcyMjQ5NTY3MTUyLjI4OTIxMTkwOTUyOTc2NjUuOTE2OTA3NTcxNzI3OTgyLjUyMDk2NTMx ODM0MDk3MzYuNjg3NjA5OTE4NjU3NDUyNi41MDQyODEwNzAxODIzMjMxNC42MzM1MDcxNTIwODMz MjU0MC40NDU3OTkzMzM0MDY4MzguNTEzODk4ODkzNDIyNTY0NjguOTEyNzA2NDAxNTM5MzQ1Mi4z Njc3NDI2OTg1OTY1NjU4Ny44MTA1NTI5NjYzNzIzMzczLjI3Njc2MzMxNDAxOTU2MzUuODgxNTAx NDQ2NjUwNjkyNS4zOTQwMTY1NjE1OTA1MDQ3Ny45NDczNDM1MDMxNTQ5MzgzLjE1MzQyNTkwNzc4 NDIz
We can see in the provided output how lines have a length of 76 chars but the last one.
The decoding process is quite similar to the other ones with the main difference that line separators are ignored while decoding.
byte[] decodedBuffer = Base64.getMimeDecoder().decode( encodedBuffer );
Wrapping files
Java 8 offers the possibility to directly encode strings and store them in a file in one step. The method wrap()
of the base64 encoders provided by Java receives and OutputStream as parameter and returns a wrapped output stream that will manipulate all content that is going to be written to the output stream. Here is an example:
String buffer = "oviedin oviedin"; File file = new File( "outputStream.txt" ); //we create a file OutputStream outputStream = new FileOutputStream( file ); // we pass the file to the output stream OutputStream wrappedOS = Base64.getEncoder().wrap( outputStream ); // using the file output stream we create a wrapped encoding one wrappedOS.write( buffer.toString().getBytes( "utf-8" ) ); // all content is encoded
This is the content of the flie:
b3ZpZWRpbiBvdmllZGlu
The opposite operation is also possible, here is shown how to read decode strings contained in a file using the wrap()
method of the decoders:
InputStream inputStream = new FileInputStream( file ); InputStream unWrappedIS = Base64.getDecoder().wrap( inputStream );
All the content that we read from the un-wrapped InputStream is going to be decoded.
Summary
So that’ all. In this artice we saw how to use the new Java 8 capabilities for encoding and decoding Strings. Java 8 offers options for decoding in different modes: Basic, URL and MIME, depending on the programmer needs. We explained also how to encode / decode strings directly to /from a file without any previous steps using the wrap()
.
We are not talking here about new technologies or great improvements in the Java language since all these features were already available using external libraries or combining different ones, but since Java update 8, encoding and decoding is out of the box in the JRE and this is very nice.
Links
Here is a list of links that can be helpful in order to learn more about encoding and decoding using Java and in general and other Java 8 new features.
- java.util.Base64
- http://en.wikipedia.org/wiki/MIME
- http://www.javacodegeeks.com/2014/05/java-8-features-tutorial.html
Download the code
All examples from this article (and some more) can be downloaded in the following link: base64.