Encoding as Base64 in Java
You need to change the import of your class:
import org.apache.commons.codec.binary.Base64;
And then change your class to use the Base64 class.
Here's some example code:
byte[] encodedBytes = Base64.encodeBase64("Test".getBytes());
System.out.println("encodedBytes " + new String(encodedBytes));
byte[] decodedBytes = Base64.decodeBase64(encodedBytes);
System.out.println("decodedBytes " + new String(decodedBytes));
Then read why you shouldn't use sun.* packages.
Update (2016-12-16)
You can now use java.util.Base64
with Java 8. First, import it as you normally do:
import java.util.Base64;
Then use the Base64 static methods as follows:
byte[] encodedBytes = Base64.getEncoder().encode("Test".getBytes());
System.out.println("encodedBytes " + new String(encodedBytes));
byte[] decodedBytes = Base64.getDecoder().decode(encodedBytes);
System.out.println("decodedBytes " + new String(decodedBytes));
If you directly want to encode string and get the result as encoded string, you can use this:
String encodeBytes = Base64.getEncoder().encodeToString((userName + ":" + password).getBytes());
See Java documentation for Base64 for more.
Base64 Java encode and decode a string
You can use following approach:
import org.apache.commons.codec.binary.Base64;
// Encode data on your side using BASE64
byte[] bytesEncoded = Base64.encodeBase64(str.getBytes());
System.out.println("encoded value is " + new String(bytesEncoded));
// Decode data on other side, by processing encoded data
byte[] valueDecoded = Base64.decodeBase64(bytesEncoded);
System.out.println("Decoded value is " + new String(valueDecoded));
Hope this answers your doubt.
Which Java library provides base64 encoding/decoding?
Java 9
Use the Java 8 solution. Note DatatypeConverter can still be used, but it is now within the java.xml.bind
module which will need to be included.
module org.example.foo {
requires java.xml.bind;
}
Java 8
Java 8 now provides java.util.Base64
for encoding and decoding base64.
Encoding
byte[] message = "hello world".getBytes(StandardCharsets.UTF_8);
String encoded = Base64.getEncoder().encodeToString(message);
System.out.println(encoded);
// => aGVsbG8gd29ybGQ=
Decoding
byte[] decoded = Base64.getDecoder().decode("aGVsbG8gd29ybGQ=");
System.out.println(new String(decoded, StandardCharsets.UTF_8));
// => hello world
Java 6 and 7
Since Java 6 the lesser known class javax.xml.bind.DatatypeConverter
can be used. This is part of the JRE, no extra libraries required.
Encoding
byte[] message = "hello world".getBytes("UTF-8");
String encoded = DatatypeConverter.printBase64Binary(message);
System.out.println(encoded);
// => aGVsbG8gd29ybGQ=
Decoding
byte[] decoded = DatatypeConverter.parseBase64Binary("aGVsbG8gd29ybGQ=");
System.out.println(new String(decoded, "UTF-8"));
// => hello world
Java buffered base64 encoder for streams
Fun fact about Base64: It takes three bytes, and converts them into four letters. This means that if you read binary data in chunks that are divisible by three, you can feed the chunks to any Base64 encoder, and it will encode it in the same way as if you fed it the entire file.
Now, if you want your output stream to just be one long line of Base64 data - which is perfectly legal - then all you need to do is something along the lines of:
private static final int BUFFER_SIZE = 3 * 1024;
try ( BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE); ) {
Base64.Encoder encoder = Base64.getEncoder();
StringBuilder result = new StringBuilder();
byte[] chunk = new byte[BUFFER_SIZE];
int len = 0;
while ( (len = in.read(chunk)) == BUFFER_SIZE ) {
result.append( encoder.encodeToString(chunk) );
}
if ( len > 0 ) {
chunk = Arrays.copyOf(chunk,len);
result.append( encoder.encodeToString(chunk) );
}
}
This means that only the last chunk may have a length that is not divisible by three and will therefore contain the padding characters.
The above example is with Java 8 Base64, but you can really use any encoder that takes a byte array of an arbitrary length and returns the base64 string of that byte array.
This means that you can play around with the buffer size as you wish.
If you want your output to be MIME compatible, however, you need to have the output separated into lines. In this case, I would set the chunk size in the above example to something that, when multiplied by 4/3, gives you a round number of lines. For example, if you want to have 64 characters per line, each line encodes 64 / 4 * 3, which is 48 bytes. If you encode 48 bytes, you'll get one line. If you encode 480 bytes, you'll get 10 full lines.
So modify the above BUFFER_SIZE to something like 4800. Instead of Base64.getEncoder()
use Base64.getMimeEncoder(64,new byte[] { 13, 10})
. And then, when it encodes, you'll get 100 full-sized lines from each chunk except the last. You may need to add a result.append("\r\n")
to the while loop.
Base 64 encode and decode example code
First:
- Choose an encoding. UTF-8 is generally a good choice; stick to an encoding which will definitely be valid on both sides. It would be rare to use something other than UTF-8 or UTF-16.
Transmitting end:
- Encode the string to bytes (e.g.
text.getBytes(encodingName)
) - Encode the bytes to base64 using the
Base64
class - Transmit the base64
Receiving end:
- Receive the base64
- Decode the base64 to bytes using the
Base64
class - Decode the bytes to a string (e.g.
new String(bytes, encodingName)
)
So something like:
// Sending side
byte[] data = text.getBytes("UTF-8");
String base64 = Base64.encodeToString(data, Base64.DEFAULT);
// Receiving side
byte[] data = Base64.decode(base64, Base64.DEFAULT);
String text = new String(data, "UTF-8");
Or with StandardCharsets
:
// Sending side
byte[] data = text.getBytes(StandardCharsets.UTF_8);
String base64 = Base64.encodeToString(data, Base64.DEFAULT);
// Receiving side
byte[] data = Base64.decode(base64, Base64.DEFAULT);
String text = new String(data, StandardCharsets.UTF_8);
Java Base64 encoding loss of data
Assuming nothing explodes due to out-of-memory errors or similar general problems, this code should be fine, with one big exception:
You are transforming the output of Base64.encodeBase64
(which is a byte[]
) to a String
without specifying the encoding.
This is generally speaking a bad idea, because it will use the platform default encoding.
In this specific case, it's unlikely to be an actual problem. Because the output of Base64 contains only ASCII characters and almost all modern platforms use a ASCII-compatible encoding as their platform default encoding (for example Android, Mac OS X and most Linux distributions use UTF-8, Windows tends to use some code-page, but the lower 128 bytes are usually also ASCII compatible).
Still, it would be better to use new String(Base64.encodeBase64(data), StandardCharsets.US_ASCII)
just to be sure (for the reasons mentioned above, ISO_8859_1
and UTF_8
would work as well, but US_ASCII
is the "correct" pick).
Decode Base64 data in Java
As of v6, Java SE ships with JAXB. javax.xml.bind.DatatypeConverter
has static methods that make this easy. See parseBase64Binary()
and printBase64Binary()
.
UPDATE: JAXB is no longer shipped with Java (since Java 11). If JAXB is required for your project, you will need to configure the relevant libraries via your dependency management system, for example Maven. If you require the compiler (xjc.exe
) you also need to download that separately.
Related Topics
What Is a Stack Trace, and How to Use It to Debug My Application Errors
How to Upload Files to a Server Using Jsp/Servlet
How to Generate Random Integers Within a Specific Range in Java
What Issues Should Be Considered When Overriding Equals and Hashcode in Java
Why Am I Getting a Noclassdeffounderror in Java
How to Create an Executable Jar With Dependencies Using Maven
Why Use Getters and Setters/Accessors
Sort a Map≪Key, Value≫ by Values
Int Division: Why Is the Result of 1/3 == 0
Sort Arraylist of Custom Objects by Property
What Is an Efficient Way to Implement a Singleton Pattern in Java
What Are the Reasons Why Map.Get(Object Key) Is Not (Fully) Generic
Difference Between Int[] Array and Int Array[]
Why Are Integer Literals With Leading Zeroes Interpreted Strangely