Base16 编码使用 16 个 ASCII 可打印字符(数字 0-9 和字母 A-F)对任意字节数据进行编码。Base16 先获取输入字符串每个字节的二进制值(不足 8 比特在高位补 0),然后将其串联进来。再按照 4 比特一组进行切分,将每组二进制数分别转换成十进制,在 Base16 字符表格中找到对应的编码串接起来就是 Base16 编码。可以看到 8 比特数据按照 4 比特切分刚好是两组,所以Base16 不可能用到填充符号 “=”。
在 Apache Commons Codec 工具库中,提供了 Base16、Base16InputStream 和 Base16OutputStream 三个类来支持 base16 编码的编解码。
该类提供 Base16 编码和解码功能,且是线程安全的。
此类的实现严格遵循 RFC4648,因此与 Base32 和 Base64 实现不同,它不忽略无效的字母字符或空格,也不提供分块或填充字符。
除了 RFC4648 中指定的功能之外,它唯一附加的功能是支持除了默认的大写字母外,还支持使用小写字母。
实例
(1)简单的使用 Base16 实现编码和解码
// 创建 Base16 对象 Base16 base16 = new Base16(); // 原始字符串 String str = "hello world"; // 加密 String encodeStr = new String(base16.encode(str.getBytes())); System.out.println(encodeStr); // 解密 System.out.println(new String(base16.decode(encodeStr.getBytes())));
输出结果:
68656C6C6F20776F726C64 hello world
(2)利用 encodeAsString() 和 encodeToString() 方法直接返回编码后的字符串表示
// 创建 Base16 对象 Base16 base16 = new Base16(); // 原始字符串 String str = "hello world"; // 加密 String encodeStr = base16.encodeAsString(str.getBytes()); String encodeStr2 = base16.encodeToString(str.getBytes()); System.out.println(encodeStr); System.out.println(encodeStr2); // 解密 System.out.println(new String(base16.decode(encodeStr)));
输出结果:
68656C6C6F20776F726C64 68656C6C6F20776F726C64 hello world
该类以流的方式(大小不受限制)提供 Base16 编码和解码。
Base16InputStream 的默认行为是 DECODE(解码),而 Base16OutputStream 的默认行为是 ENCODE(编码),但是可以使用其他构造函数来覆盖此行为。实例:
(1)使用默认构造参数,通过 read() 方法读取解码后的信息。如下:
String encodeStr = "68656C6C6F20776F726C64"; ByteArrayInputStream input = new ByteArrayInputStream(encodeStr.getBytes()); Base16InputStream base16InputStream = new Base16InputStream(input); // 从 Base16InputStream 中解码数据 byte[] buffer = new byte[1024]; int len = base16InputStream.read(buffer); System.out.println(new String(buffer, 0, len));
输出结果:
hello world
(2)通过构造函数更改 Base16InputStream 的默认行为。如下:
String encodeStr = "hello world"; ByteArrayInputStream input = new ByteArrayInputStream(encodeStr.getBytes()); // 通过构造函数改变 Base16InputStream 默认行为 // 使得 Base16InputStream 类 read 方法读取数据为编码,而不是解码 Base16InputStream base16InputStream = new Base16InputStream(input, true); // 从 Base16InputStream 中编码数据 byte[] buffer = new byte[1024]; int len = base16InputStream.read(buffer); System.out.println(new String(buffer, 0, len));
输出结果:
68656C6C6F20776F726C64
该类以流的方式(大小不受限制)提供 Base16 编码和解码。
Base16OutputStream 的默认行为是 ENCODE(编码),而 Base16InputStream 的默认行为是 DECODE(解码)。但是可以通过使用其他构造函数来覆盖此行为,你可以参考 Base16InputStream 类示例。实例:
ByteArrayOutputStream output = new ByteArrayOutputStream(); Base16OutputStream base16OutputStream = new Base16OutputStream(output); base16OutputStream.write("hello world".getBytes()); base16OutputStream.close(); // 输出编码结果 System.out.println(new String(output.toByteArray()));
输出结果:
68656C6C6F20776F726C64