BASE64的介绍及用Java语言编写代码实现

BASE64的介绍及用Java语言编写代码实现

首页角色扮演代号R64更新时间:2024-04-22

1、引言

说到加密解密,很多书籍都会把BASE64扯进来,并且和MD5、SHA放在一起讲解,作为不可逆加密方案的一部分。

但这些书籍,在描述BASE64时,又会特别指出,BASE64并不是不可逆加密方案,是可逆的,并且根本算不上加密。

本质上来说,BASE64只是将二进制数据(包括字符数据),换了一种编码方式,变成了人不可以直接阅读的文本。

2、BASE64的定义

BASE64是在RFC2045中定义的,大家在百度中输入“RFC2045”,即可找到该文档的全文。

RFC2045用于定义MIME(多用途因特网邮件扩展协议),定义了消息体的格式。该文档的6.8节(Base64 Content-Transfer-Encoding)详细描述了BASE64编码的规则。

BASE64的编码的详细描述如下:

(1)可以对任意的字节序列进行编码;

(2)编码的结果比源码长33%;

(3)BASE64使用了65个ASCII字符来表示编码结果;

(4)BASE64中的64个字符代表6bit的值;

(5)BASE64除了表示值的64个字符外,还有一个等号字符=,有特殊含义;

(6)BASE64将24bit,也就是3个字节,变成4个字符;

(7)BASE64将原始数据当成大端格式的字节序列,即第一个bit是高位,对应的英语表示是most-significant-bit first;

(8)6bit值与BASE64的字符映射关系如下:

(9)BASE64编码结果中的回车、换行以及其他字符,必须被忽略;

(10)输入的字节数组,按照每3字节变成生成4个字符,如果最后不足3字节,则没法凑足成6bit的序列,不足的部分通过补充0来满足;

(11)如果输入的字节数组,最后只剩一个字节未编码,则只能凑足两个6bit,输出的结果带两个等号==;

(12)如果输入的字节数组,最后只剩两个字节未编码,则只能凑足三个6bit,输出的结果带一个等号=。

这样流水账式的描述,虽然挺繁琐,却是程序员最习惯的。

3、手工计算BASE64编码值

如果我们对三字节序列0x00 0x00 0x00进行BASE64编码,相当于对四个6bit值 0,0,0,0进行映射转换,结果自然是AAAA;

如果我们对两字节序列0x00 0x00进行BASE64编码,相当于对补零之后的三个6bit值0,0,0进行映射转换,结果是AAA=;

如果我们对单字节0x00进行BASE64编码,相当于对补零之后的两个6bit值0,0进行映射转换,结果是AA==;

如果对于非零的值,例如对三字节序列0x01 0x01 0x01进行转换,以字节序列的视角来看,是这样的:

如果以6bit序列的视角来看,则是这样的:

相当于4个6bit的值 0,16,4,1,进行映射转换,结果就是AQEB。

4、使用JDK的BASE64编码功能

JDK提供了多个关于BASE64编码的类,这里使用BASE64Encoder类来完成。代码如下:

package com.flying.base; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import sun.misc.BASE64Encoder; @SpringBootApplication public class BaseApplication { public static void main(string[] args) { SpringApplication.run(BaseApplication.class, args); BASE64Encoder base64Encoder = new BASE64Encoder(); byte[] bytes; bytes = new byte[]{0, 0, 0}; System.out.println("BASE64 of {0, 0, 0} is: " base64Encoder.encode(bytes)); bytes = new byte[]{0, 0}; System.out.println("BASE64 of {0, 0} is: " base64Encoder.encode(bytes)); bytes = new byte[]{0}; System.out.println("BASE64 of {0} is: " base64Encoder.encode(bytes)); bytes = new byte[]{1, 1, 1}; System.out.println("BASE64 of {1, 1, 1} is: " base64Encoder.encode(bytes)); } }

程序的运行结果为:

可以看到,程序的运行结果和手工计算的结果相同。

5、自己写代码实现简易的BASE64编码功能

BASE64编码的规则很简单,我们完全可以自己实现一个简易版本的,这是我临时编写的代码,大家将就着看一下:

package com.flying.base; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class BaseApplication { public static void main(String[] args) { SpringApplication.run(BaseApplication.class, args); byte[] bytes; bytes = new byte[]{0, 0, 0}; System.out.println("Self BASE64 of {0, 0, 0} is: " base64Encode(bytes)); bytes = new byte[]{0, 0}; System.out.println("Self BASE64 of {0, 0} is: " base64Encode(bytes)); bytes = new byte[]{0}; System.out.println("Self BASE64 of {0} is: " base64Encode(bytes)); bytes = new byte[]{1, 1, 1}; System.out.println("Self BASE64 of {1, 1, 1} is: " base64Encode(bytes)); } private static char[] base64Characters ={ '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', ' ', '/' }; static String base64Encode(byte[] bytes){ if (bytes == null || bytes.length == 0){ return ""; } int index1, index2, index3, index4; StringBuilder stringBuilder = new StringBuilder(); int timesOfThree = bytes.length / 3; for (int i=0; i<timesOfThree; i ){ index1 = bytes[i*3] >> 2; index1 = index1 & 0x3F; index2 = bytes[i*3] & 0x03; index2 = index2 << 4; index2 = index2 | ((bytes[i*3 1] & 0xF0) >> 4); index2 = index2 & 0x3F; index3 = bytes[i*3 1] & 0x0F; index3 = index3 << 2; index3 = index3 | ((bytes[i*3 2] & 0xC0) >> 6); index3 = index3 & 0x3F; index4 = bytes[i*3 2] & 0x3F; stringBuilder.append(base64Characters[index1]).append(base64Characters[index2]).append(base64Characters[index3]).append(base64Characters[index4]); } int remainPos = bytes.length / 3; remainPos = remainPos * 3; switch (bytes.length % 3){ case 1: index1 = bytes[remainPos*3] >> 2; index1 = index1 & 0x3F; index2 = bytes[remainPos*3] & 0x03; index2 = index2 << 4; index2 = index2 & 0x3F; stringBuilder.append(base64Characters[index1]).append(base64Characters[index2]).append('=').append('='); break; case 2: index1 = bytes[remainPos*3] >> 2; index1 = index1 & 0x3F; index2 = bytes[remainPos*3] & 0x03; index2 = index2 << 4; index2 = index2 | ((bytes[remainPos*3 1] & 0xF0) >> 4); index2 = index2 & 0x3F; index3 = bytes[remainPos*3 1] & 0x0F; index3 = index3 << 2; index3 = index3 & 0x3F; stringBuilder.append(base64Characters[index1]).append(base64Characters[index2]).append(base64Characters[index3]).append('='); break; default: break; } return stringBuilder.toString(); } }

程序的运行结果如下:

上面的示例代码,只进行了BASE64的编码,如果你感兴趣,可以尝试编写BASE64解码的程序。

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved