Base64编解码

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Base64编解码

一、编码原理

Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示。编码后的数据比原来的数据略长,是原来的4/3倍。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9 ,这样共有62个字符,此外两个可打印符号在不同的系统中而不同(Base64de 编码表如下所示)。Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据。包括MIME的email,email via MIME, 在XML中存储复杂数据.

Base64编码表

二、编码流程

步骤1:将要编码的所有字符都转化成对应的ASCII码。

步骤2:将所有的ASCII码转换成对应的8位长的二进制数。

步骤3:将所得的二进制数从高位到低位开始分成6位一组,最后一组不足六的则补充0

步骤4:将每组二进制数转换成十进制数,然后对照base64的编码表查找得到相应的编码。

注意:1、要求被编码字符是8bit的,所以须在ASCII编码范围内,\u0000-\u00ff,中文就不行。

2、如果被编码的字符串中字符的个数为3的倍数,按照上面的步骤即可得到正确的base64编码。但是如果不是3的倍数则要分情况讨论。如果是3的倍数余1,则要在编好的码字后面加上两个“=”,如果是3的倍数余2,这要在编好的码字后面加上一个“=”。(例如w的base64编码为dw==,w1的base64编码为dzE=)

下面我们来对具体的字符串进行编码举例,以便更好的理解编码流程:

编码「Man」

在此例中,Base64算法将三个字符编码为4个字符

特殊情况

A的编码为QQ= =

BC的编码为QkM=

三、核心算法程序

算法的基本原理如下:由于每次转换都需要6个bit,而这6个bit可能都来自一个字节,也可以来自前后相临的两个字节。定义两个变量:prevByteBitCount和nextByteBitCount,这两个变量分别表述从前一个和后一个节字取得的bit数。如果prevByteBitCount为0,表示6个bit全部来自下一个字节的高6位。如果nextByteBitCount = 0,表示6个bit全部来自前一个字节的低6位。最后通过适当的移位获得所需要的6个bit,再在上面的base64编码表中查找相应的字符。算法的实现代码如下:

public static String encoder(byte[] bytes)

{

StringBuilder result = new StringBuilder();

String base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // prevByteBitCount表示从前一个字节取得的bit数,nextByteBitCount表示从后一个字节取得的bit数

int prevByteBitCount = 0, nextByteBitCount = 6;

// i表示当前的数组索引,n表示已经处理的位数

int i = 0, n = 0;

// byteCount表示总的位数

int byteCount = 8 * bytes.length;

byte b = 0;

while (true)

{

// 处理从前后两个字节取得位数的情况

if (prevByteBitCount > 0 && nextByteBitCount > 0)

{

// 将前一个字节的低位向左移nextByteBitCount个bit,并使下一个字节的高位(nextByteBitCount指定的位数)右移到字节的最低位,

// 然后将两个位移结果进行逻辑或,也就是将从前一个字节和后一个字节取得的相应的bit合并为一个字节的低位

b = (byte) (((0xff & bytes[i]) << nextByteBitCount) | ((0xff & bytes[i + 1]) >> (8 - nextByteBitCount)));

// 将逻辑或后的结果的最高两个bit置成0

b = (byte) (b & 0x3f);

prevByteBitCount = 8 - nextByteBitCount;

nextByteBitCount = 6 - prevByteBitCount;

}

// 处理从后一个字节取得高6位的情况

else if (prevByteBitCount == 0)

{

// 后一个字节的高6位右移动低6位

b = (byte) ((0xff & bytes[i]) >> (8 - nextByteBitCount));

// 处理后面的位时,就是从前一个字节取2个bit,从后一个字字取4个bit prevByteBitCount = 2;

nextByteBitCount = 4;

}

// 处理从前一个字节取得低6位的情况

else if (nextByteBitCount == 0)

{

// 将前一个字节的最高两个bit置成0

b = (byte) (0x3f & bytes[i]);

// 处理后面的位时,从后一个字节取6个bit

prevByteBitCount = 0;

nextByteBitCount = 6;

}

result.append(base64.charAt(b));

n += 6;

i = n / 8;

int remainBitCount = byteCount - n;

if (remainBitCount < 6)

{

// 将剩余的bit补0后,仍然需要在base64编码表中查找相应的字符,并添加到结果字符串的最后

if (remainBitCount > 0)

{

b = bytes[bytes.length - 1];

b = (byte) (0x3f & (b << (6 - remainBitCount)));

result.append(base64.charAt(b));

}

break;

}

}

// 如果总bit数除3的余数为1,加一个“=”,为2,加两个“=”

n = byteCount % 3;

for (i = 0; i < n; i++)

result.append("=");

return result.toString();

}

对于程序的理解:这个程序应该只是总程序的一部分,它主要实现了对二进

相关文档
最新文档