de.timroes.base64.Base64 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aXMLRPC Show documentation
Show all versions of aXMLRPC Show documentation
Lightweight Java XML-RPC working also on Android.
package de.timroes.base64;
import java.util.HashMap;
/**
* A Base64 en/decoder. You can use it to encode and decode strings and byte arrays.
*
* @author Tim Roes
*/
public class Base64 {
private static final char[] code = ("=ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz0123456789+/").toCharArray();
private static final HashMap map = new HashMap();
private Base64() {}
static {
for(int i = 0; i < code.length; i++) {
map.put(code[i], (byte)i);
}
}
/**
* Decode a base64 encoded string to a byte array.
*
* @param in A string representing a base64 encoding.
* @return The decoded byte array.
*/
public static byte[] decode(String in) {
in = in.replaceAll("\\r|\\n","");
if(in.length() % 4 != 0) {
throw new IllegalArgumentException("The length of the input string must be a multiple of four.");
}
if(!in.matches("^[A-Za-z0-9+/]*[=]{0,3}$")) {
throw new IllegalArgumentException("The argument contains illegal characters.");
}
byte[] out = new byte[(in.length()*3)/4];
char[] input = in.toCharArray();
int outi = 0;
int b1, b2, b3, b4;
for(int i = 0; i < input.length; i+=4) {
b1 = map.get(input[i]) - 1;
b2 = map.get(input[i+1]) - 1;
b3 = map.get(input[i+2]) - 1;
b4 = map.get(input[i+3]) - 1;
out[outi++] = (byte)(b1 << 2 | b2 >>> 4);
out[outi++] = (byte)((b2 & 0x0F) << 4 | b3 >>> 2);
out[outi++] = (byte)((b3 & 0x03) << 6 | (b4 & 0x3F));
}
if(in.endsWith("=")) {
byte[] trimmed = new byte[out.length - (in.length() - in.indexOf("="))];
System.arraycopy(out, 0, trimmed, 0, trimmed.length);
return trimmed;
}
return out;
}
/**
* Decode a base64 encoded string to a string.
*
* @param in The string representation of the base64 encoding.
* @return The decoded string in the default charset of the JVM.
*/
public static String decodeAsString(String in) {
return new String(decode(in));
}
/**
* Encode a String and return the encoded string.
*
* @param in A string to encode.
* @return The encoded byte array.
*/
public static String encode(String in) {
return encode(in.getBytes());
}
/**
* Encode a Byte array and return the encoded string.
*
* @param in A string to encode.
* @return The encoded byte array.
*/
public static String encode(Byte[] in) {
byte[] tmp = new byte[in.length];
for(int i = 0; i < tmp.length; i++) {
tmp[i] = in[i];
}
return encode(tmp);
}
/**
* Encode a byte array and return the encoded string.
*
* @param in A string to encode.
* @return The encoded byte array.
*/
public static String encode(byte[] in) {
StringBuilder builder = new StringBuilder(4 * ((in.length+2)/3));
byte[] encoded = encodeAsBytes(in);
for(int i = 0; i < encoded.length; i++) {
builder.append(code[encoded[i]+1]);
if(i % 72 == 71)
builder.append("\n");
}
return builder.toString();
}
/**
* Encode a String and return the encoded byte array. Bytes that has been
* appended to pad the string to a multiple of four are set to -1 in the array.
*
* @param in A string to encode.
* @return The encoded byte array.
*/
public static byte[] encodeAsBytes(String in) {
return encodeAsBytes(in.getBytes());
}
/**
* Encode a byte array and return the encoded byte array. Bytes that has been
* appended to pad the string to a multiple of four are set to -1 in the array.
*
* @param inArray A string to encode.
* @return The encoded byte array.
*/
public static byte[] encodeAsBytes(byte[] inArray) {
// Output string must be 4 * floor((n+2)/3) large
byte[] out = new byte[4 * ((inArray.length+2)/3)];
// Create padded input array with the next largest length that is a multiple of 3
byte[] in = new byte[(inArray.length+2)/3*3];
// Copy content form unpadded to padded array
System.arraycopy(inArray, 0, in, 0, inArray.length);
int outi = 0;
for(int i = 0; i < in.length; i+=3) {
out[outi++] = (byte)((in[i] & 0xFF) >>> 2);
out[outi++] = (byte)(((in[i] & 0x03) << 4) | ((in[i+1] & 0xFF) >>> 4));
out[outi++] = (byte)(((in[i+1] & 0x0F) << 2) | ((in[i+2] & 0xFF) >>> 6));
out[outi++] = (byte)(in[i+2] & 0x3F);
}
for(int i = in.length - inArray.length; i > 0; i--) {
out[out.length - i] = -1;
}
return out;
}
}