关于BASE64编码,建议参看WIKI中的相关说明。
1、编码:
public static byte[] base64encode(byte[] inbuf) {
int size = inbuf.length;
byte[] outbuf = new byte[((inbuf.length + 2) / 3) * 4];
int inpos, outpos;
int val;
// 情况1:大于等于3
for (inpos = 0, outpos = 0; size >= 3; size -= 3, outpos += 4) {
val = inbuf[inpos++] & 0xff;
val <<= 8;
val |= inbuf[inpos++] & 0xff;
val <<= 8;
val |= inbuf[inpos++] & 0xff;
// 到此val中存储了3*8=24个二进制位,然后分4次,每次6个二进制位输出
outbuf[outpos + 3] = (byte) pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos + 2] = (byte) pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos + 1] = (byte) pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos + 0] = (byte) pem_array[val & 0x3f];
}
// 情况2:等于1或者等于2
if (size == 1) {
val = inbuf[inpos++] & 0xff;
val <<= 4;
// 到此val中实际有效二进制位8+4=12个,并且后4个都为0
outbuf[outpos + 3] = (byte) '='; // pad character;
outbuf[outpos + 2] = (byte) '='; // pad character;
outbuf[outpos + 1] = (byte) pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos + 0] = (byte) pem_array[val & 0x3f];
} else if (size == 2) {
val = inbuf[inpos++] & 0xff;
val <<= 8;
val |= inbuf[inpos++] & 0xff;
val <<= 2;
// 得到此val中实际有效二进制位为8+8+2=18个,并且后2个为0
outbuf[outpos + 3] = (byte) '='; // pad character;
outbuf[outpos + 2] = (byte) pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos + 1] = (byte) pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos + 0] = (byte) pem_array[val & 0x3f];
}
return outbuf;
}
private final static char pem_array[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 1
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 2
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 3
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 4
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 5
'w', 'x', 'y', 'z', '0', '1', '2', '3', // 6
'4', '5', '6', '7', '8', '9', '+', '/' // 7
};
测试:
public static void main(String[] args) {
String [] strs = {"leasure.","easure.","asure.","sure."};
for(String str:strs){
System.out.println(new String(base64encode(str.getBytes())));
}
}
输出:
bGVhc3VyZS4=
ZWFzdXJlLg==
YXN1cmUu
c3VyZS4=
2、反编码:
public static byte[] base64decode(byte[] inbuf) {
int size = (inbuf.length / 4) * 3;
if (inbuf[inbuf.length - 1] == '=') {
size--;
if (inbuf[inbuf.length - 2] == '=')
size--;
}
byte[] outbuf = new byte[size];
int inpos = 0, outpos = 0;
size = inbuf.length;
while (size > 0) {
int val;
int osize = 3;
val = pem_convert_array[inbuf[inpos++] & 0xff];
val <<= 6;
val |= pem_convert_array[inbuf[inpos++] & 0xff];
val <<= 6;
if (inbuf[inpos] != '=') // End of this BASE64 encoding
val |= pem_convert_array[inbuf[inpos++] & 0xff];
else
osize--;
val <<= 6;
if (inbuf[inpos] != '=') // End of this BASE64 encoding
val |= pem_convert_array[inbuf[inpos++] & 0xff];
else
osize--;
if (osize > 2)
outbuf[outpos + 2] = (byte) (val & 0xff);
val >>= 8;
if (osize > 1)
outbuf[outpos + 1] = (byte) (val & 0xff);
val >>= 8;
outbuf[outpos] = (byte) (val & 0xff);
outpos += osize;
size -= 4;
}
return outbuf;
}
private final static char pem_array[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 1
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 2
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 3
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 4
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 5
'w', 'x', 'y', 'z', '0', '1', '2', '3', // 6
'4', '5', '6', '7', '8', '9', '+', '/' // 7
};
private final static byte pem_convert_array[] = new byte[256];
static {
// 将数组中的每个元素的所有二进制位均初始化为1
for (int i = 0; i < 255; i++)
pem_convert_array[i] = -1;
for (int i = 0; i < pem_array.length; i++)
pem_convert_array[pem_array[i]] = (byte) i;
}
测试:
public static void main(String[] args) {
String strs[] = { "bGVhc3VyZS4=", "ZWFzdXJlLg==", "YXN1cmUu", "c3VyZS4=" };
for(String str:strs){
System.out.println(new String(base64decode(str.getBytes())));
}
}
输出:
leasure.
easure.
asure.
sure.