维基百科说base64
Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。一些如uuencode的其他编码方法,和之后binhex的版本使用不同的64字符集来代表6个二进制数字,但是它们不叫Base64。
Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据。包括MIME的email、在XML中存储复杂数据。
base64编码原理
1、将原始数据以先后顺序每3个字节分成一组。在每一组中,每组的字节(一组字节包含38=24位)按高低位顺序分为4段每段6为(46=24),然后对其进行编码。
编码包含的字符为:A-Z、a-z、0-9、+、/。共64个字符:26 + 26 + 10 + 1 + 1 = 64。(注:其实是65个字符,“=”是填充字符)
2、密文会把每76个字符数据后加一个换行符。
3、原始数据字节长度除3余1,则需要补充两个字节即:补16个0;若原始数据长度除3余2,则需要补充一个字节即:补8个0。转化的时候会从编码最后开始算起每6个0转化成 =。
4、base64编码后会比原始数据多多少呢?下面这个公式可以解决
计算方式:1*(4/3)*((76+1)/76)≈1.351
base编完码之后比以前多了%35,但是base64 编码能够被 gzip 压缩,压缩率能达到 50% 以上。
java实现代码:
private static String byteArrayToBase64(byte[] a) {
int aLen = a.length; //总长度
int numFullGroups = aLen / 3; //以3个byte组成以4个字符为一组的组数
int numBytesInPartialGroup = aLen - 3 * numFullGroups; //余数
int resultLen = 4 * ((aLen + 2) / 3); //输出长度总是4倍数,如果有余数,(aLen+2)/3保证将余数包含,并有空间放置填充符=
StringBuffer result = new StringBuffer(resultLen);
int inCursor = 0;
for (int i = 0; i < numFullGroups; i++) {
int byte0 = a[inCursor++] & 0xff;
int byte1 = a[inCursor++] & 0xff;
int byte2 = a[inCursor++] & 0xff;
result.append(intToBase64[byte0 >> 2]);
result.append(intToBase64[(byte0 << 4) & 0x3f | (byte1 >> 4)]);
result.append(intToBase64[(byte1 << 2) & 0x3f | (byte2 >> 6)]);
result.append(intToBase64[byte2 & 0x3f]);
}
//处理余数
if (numBytesInPartialGroup != 0) {
int byte0 = a[inCursor++] & 0xff;
result.append(intToBase64[byte0 >> 2]);
//余数为1
if (numBytesInPartialGroup == 1) {
result.append(intToBase64[(byte0 << 4) & 0x3f]);
result.append("==");
} else {
// 余数为2
int byte1 = a[inCursor++] & 0xff;
result.append(intToBase64[(byte0 << 4) & 0x3f | (byte1 >> 4)]);
result.append(intToBase64[(byte1 << 2) & 0x3f]);
result.append('=');
}
}
return result.toString();
}
base64解码原理
根据上面我介绍的base64编码原理,取反结合base64反向索引表就可以得到源码了。