Base64 编码是使用 64 个可打印 ASCII 字符(A-Z、a-z、0-9、+、/)将任意字节序列数据编码成 ASCII 字符串;另外,还有一个 “=” 符号用作填充。
Base64 将输入字符串按字节切分,取得每个字节对应的二进制值(若不足 8 比特则高位补 0),然后将这些二进制数值串联起来,再按照 6 比特一组进行切分(因为 2^6 = 64),最后一组若不足 6 比特则末尾补 0。将每组二进制值转换成十进制,然后在 Base64 字符映射表格中找到对应的符号并串联起来就是 Base64 编码结果。
由于二进制数据是按照 8 比特一组进行传输,因此 Base64 按照 6 比特一组切分的二进制数据必须是 24 比特的倍数(6 和 8 的最小公倍数)。24 比特就是 3 个字节,如果不足 3 字节,则使用 “=” 进行填充。如下:
若最后一组只有 1 个输入数据,则在编码结果后加 2 个=;
若最后一组只有 2 个输入数据,则在编码结果后加 1 个 =。
在 Apache Commons Codec 库中,提供了 Base64、Base64InputStream 和 Base64OutputStream 三个类实现 base64 编码和解码。
该类提供了 RFC2045 中定义的 Base64 编码的编码和解码功能,且该类还是线程安全的。此类实现了 RFC2045 中的第 6.8 节(Content-Transfer-Encoding)。
可以使用各种构造函数以以下方式对类进行参数化:
URL安全模式:默认关闭
行长:默认为76
行分隔符:默认为CRLF(“\r\n”)
URL安全参数仅适用于编码操作。解码可无缝处理两种模式。
由于此类直接在字节流而不是字符流上运行,因此它被硬编码为仅编码/解码与较低的 127 个 ASCII 兼容的字符编码(ISO-8859-1,Windows-1252,UTF-8 等等)
构造方法说明
public Base64(int lineLength, byte[] lineSeparator, boolean urlSafe, CodecPolicy decodingPolicy)
创建用于解码(所有模式)和 URL 不安全模式下编码的 Base64 编解码器。编码时,在构造函数中给出了行长和行分隔符,编码表为STANDARD_ENCODE_TABLE。参数说明:
lineLength:每行编码数据最多为给定长度(四舍五入为最接近的 4 的倍数)。如果 lineLength <= 0,则输出将不会分为几行。
lineSeparator:每一行编码数据将以此字节序列结尾。
urlSafe:我们将使用 “-” 和 “_” 字符分别替换 “+” 和 “/” 字符。urlSafe 参数仅仅适用于编码操作,解码可无缝处理两种模式。 注意:使用网址安全字母时,不会添加任何填充。
decodingPolicy:指定解码策略。
方法说明:
static byte[] decodeBase64(byte[] base64Data) 将给定的数据 base64 解码
static byte[] decodeBase64(String base64String)
static BigInteger decodeInteger(byte[] pArray) 根据诸如W3C的XML签名之类的加密标准对byte64编码的整数进行解码。
static byte[] encodeBase64(byte[] binaryData) 使用base64算法对二进制数据进行编码,但不对输出进行分块。
static String encodeBase64String(byte[] binaryData)
static byte[] encodeBase64(byte[] binaryData, boolean isChunked) 使用base64算法对二进制数据进行编码,可以选择将输出分块为76个字符块。
static byte[] encodeBase64(byte[] binaryData, boolean isChunked, boolean urlSafe)
static byte[] encodeBase64(byte[] binaryData, boolean isChunked, boolean urlSafe, int maxResultSize)
static byte[] encodeBase64Chunked(byte[] binaryData)
static byte[] encodeBase64URLSafe(byte[] binaryData) 使用base64算法的URL安全变体对二进制数据进行编码,但不对输出进行分块。
static String encodeBase64URLSafeString(byte[] binaryData)
static byte[] encodeInteger(BigInteger bigInteger) 根据诸如W3C的XML签名之类的加密标准将其编码为byte64编码的整数。
boolean isBase64(String base64) 测试给定的String,以查看它是否仅包含Base64字母内的有效字符。
boolean isBase64(byte octet)
boolean isBase64(byte[] arrayOctet) 测试给定的字节数组,以查看它是否仅包含Base64字母内的有效字符。
boolean isInAlphabet(byte octet) 返回 octet 参数是否在 Base64 字母表中
boolean isUrlSafe() 返回当前的编码模式
实例
(1)Base64类简单实用
Base64 base64 = new Base64(); byte[] bytes = base64.encode("hello world".getBytes()); System.out.println(new String(bytes));
输出结果:
aGVsbG8gd29ybGQ=
(2)Base64类编码和解码
Base64 base64 = new Base64(); byte[] bytes = base64.encode("hello world".getBytes()); String encodeResult = new String(bytes); System.out.println( encodeResult ); System.out.println( new String(base64.decode(encodeResult)) );
输出结果:
aGVsbG8gd29ybGQ= hello world
(3)指定行长度和换行符
Base64 base64 = new Base64(10, "##".getBytes()); byte[] bytes = base64.encode("administrator".getBytes()); System.out.println( new String(bytes) );
输出结果:
YWRtaW5p##c3RyYXRv##cg==##
(4)实用 URL 安全的 Base64 编码和解码
System.out.println("加密数据:"); // 加密数据,返回字节数组 System.out.println(new String(Base64.encodeBase64("hello world".getBytes()))); // 加密数据,返回字符串 System.out.println(Base64.encodeBase64String("hello world".getBytes())); // 使用 Base64 算法的 URL 安全变体对二进制数据进行编码,但不对输出分块。 // URL 安全的变体输出 - 和 _ 而不是 + 和 / 字符。 // 注意:不添加填充物,即 =。 System.out.println(new String(Base64.encodeBase64URLSafe("hello world".getBytes()))); System.out.println(Base64.encodeBase64URLSafeString("hello world".getBytes())); System.out.println("解密数据:"); String encodeStr = "aGVsbG8gd29ybGQ="; // 解密数据,接收字符串参数 System.out.println(new String(Base64.decodeBase64(encodeStr))); // 解密数据,接收字节数组参数 System.out.println(new String(Base64.decodeBase64(encodeStr.getBytes())));
输出结果:
加密数据: aGVsbG8gd29ybGQ= aGVsbG8gd29ybGQ= aGVsbG8gd29ybGQ aGVsbG8gd29ybGQ 解密数据: hello world hello world
该类以流的方式(大小不受限制)提供 Base64 编码和解码。编码时,默认的 lineLength 为 76 个字符,默认的 lineEnding 为 CRLF,但是可以使用适当的构造函数来覆盖这些字符。
Base64InputStream 的默认行为是 DECODE(解码),而 Base64OutputStream 的默认行为是 ENCODE(编码),也可以使用其他构造函数来覆盖此行为。实例:
String source = "aGVsbG8gd29ybGQ="; ByteArrayInputStream inputStream = new ByteArrayInputStream(source.getBytes()); Base64InputStream base64InputStream = new Base64InputStream(inputStream); // 从 read 方法读取,直接解码 byte[] buffer = new byte[1024]; int len = base64InputStream.read(buffer); System.out.println(new String(buffer, 0, len));
输出结果:
hello world
该类以流的方式(大小不受限制)提供 Base64 编码和解码。编码时,默认的 lineLength 为 76 个字符,默认的 lineEnding 为 CRLF,但是可以使用适当的构造函数来覆盖这些字符。
Base64OutputStream 的默认行为是 ENCODE(编码),而 Base64InputStream 的默认行为是 DECODE(解码)。但是可以通过使用其他构造函数来覆盖此行为。实例:
String source = "hello world"; ByteOutputStream outputStream = new ByteOutputStream(); Base64OutputStream base64OutputStream = new Base64OutputStream(outputStream); base64OutputStream.write(source.getBytes()); base64OutputStream.close(); // 获取编码结果 String result = new String(outputStream.getBytes()); System.out.println(result);
输出结果:
aGVsbG8gd29ybGQ=
查看 Base64 类的详细用法,请参考官网 API 文档,地址如下:
http://commons.apache.org/proper/commons-codec/apidocs/index.html