Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。
Base64要求把每三个8Bit的字节转换为四个6Bit的字节(38 = 46 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。
规则
关于这个编码的规则:
①把3个字节变成4个字节。
②每76个字符加一个换行符。
③最后的结束符也要处理。
例子:
转换前 11111111, 11111111, 11111111 (二进制)
转换后 00111111, 00111111, 00111111, 00111111 (二进制)
把三个分割成4个。
上面的三个字节是原文,下面的四个字节是转换后的Base64编码格式。
转换后,我们用一个码表来得到我们想要的字符串(也就是最终的Base64编码)这个表是这样的:(摘自RFC2045)
转换表
如果要编码的字节数不能被3整除,最后会多出1个或2个字节,那么可以使用下面的方法进行处理:
先使用0字节值在末尾补足,使其能够被3整除,然后再进行Base64的编码。
在编码后的Base64文本后加上一个或两个=号,代表补足的字节数。
也就是说:
当最后剩余两个八位(待补足)字节(2个byte)时,最后一个6位的Base64字节块有四位是0值,最后附加上两个等号;
如果最后剩余一个八位(待补足)字节(1个byte)时,最后一个6位的base字节块有两位是0值,最后附加一个等号。
参考下表:
编码过程代码:
static char[] base64_list = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
public static void main(String[] args) {
base64_("百度百科");
}
public static char base64_list(int num) {
return base64_list[num];
}
public static void base64_(String a) {
String str = "";
byte[] bytes = a.getBytes();//转化为字节数组
int yCount = bytes.length % 3;
for (int i = 0; i < bytes.length - yCount; i = i + 3) {
int v = ((bytes[i] & 0XFF) << 16) | ((bytes[i + 1] & 0XFF) << 8) | (bytes[i + 2] & 0XFF);//隐式转换 byte进行位运算后自动转换成int
int o1 = v >>> 18 & 0x3F;//共24位 右移18位 余6位 取0x3F=6位数
int o2 = v >>> 12 & 0x3F;
int o3 = v >>> 6 & 0x3F;
int o4 = v & 0x3F;
str = str + base64_list(o1) + base64_list(o2) + base64_list(o3) + base64_list(o4);
}
if (yCount == 1) {//余数为1的情况
byte b = bytes[bytes.length - 1];
str += base64_list((b & 0xFF) >>> 2);
str += base64_list((b & 0xFF )<< 4 & 0x3F);
str += "==";
} else if (yCount == 2) {//余数为2的情况
int aa = ((bytes[bytes.length - 2] & 0xFF) << 8) | (bytes[bytes.length - 1] & 0xFF);
int a1 = aa >>> 10 & 0x3F;//余6位
int a2 = aa >>> 4 & 0x3F;//余12位
int a3 = aa << 2 & 0x3F;//余18位 取6位
str += base64_list(a1) + base64_list(a2)+ base64_list(a3);
str += "=";
}
System.out.println(str);
}
解码过程代码:
public static void main(String[] args) {
Base64__01("55m+5bqm55m+56eR");
}
static char[] base64_list = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
public static void Base64__01(String str) {
String str1 = str.split("=")[0];//截取等号前面的字符
char[] chars = str1.toCharArray();//转换成char数组
int[] ints2 = new int[chars.length];
String base_list01 = String.valueOf(base64_list);//把上面的字符数组转换成字符串
for (int i = 0; i < chars.length; i++) {
ints2[i] = base_list01.indexOf(chars[i]);//查找位置 得到的位数存入数组
}
byte[] bytes = new byte[ints2.length/4*3];
int count = 0;
for (int i = 0; i < ints2.length; i = i + 4) {
int v = ((ints2[i]) << 18) | ((ints2[i + 1]) << 12) | ((ints2[i + 2]) << 6) | (ints2[i + 3]);
int o1 = v >>> 16 & 0xFF;//右移16位 取8位
int o2 = v >>> 8 & 0xFF;
int o3 = v & 0xFF;
bytes[count] = (byte) o1;//存入byte数组
bytes[count + 1] = (byte) o2;
bytes[count + 2] = (byte) o3;
count = count + 3;
}
System.out.println(new String(bytes));
}