Base16 应用与原理解析
简介:
Base16编码使用16个ASCII字符对任何数据进行编码,Base16与Base64的实现原理类似,同样是将原数据二进制形式取指定位数转换为ASCII码。首先获取数据的二进制形式,将其串联起来,每4个比特为一组进行切分,每一组内的4个比特可转换到指定的16个ASCII字符中的一个,将转换后的ASCII字符连接起来,就是编码后的数据。
字典:
Base16依赖更小的字典,Base16编码时每4个字符为一个分组,字典的长度为24=16,字典值如下:
Value | Encoding | Value | Encoding | Value | Encoding | Value | Encoding |
---|---|---|---|---|---|---|---|
0 | 0 | 4 | 4 | 8 | 8 | 12 | C |
1 | 1 | 5 | 5 | 9 | 9 | 13 | D |
2 | 2 | 6 | 6 | 10 | A | 14 | E |
3 | 3 | 7 | 7 | 11 | B | 15 | F |
字典中包含0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F,没有包含Base64中的特殊字符,为什么呢。原来是一个字节是8个比特,Base16编码是以4个比特为一组,一个字节正好分为两组,所以不需要补位,只要按照值在字典中查找即可。
演示示例:
Base16的实现较少,在dnsjava中提供了Base16的实现,dnsjava的Maven坐标如下:
<dependency>
<groupId>dnsjava</groupId>
<artifactId>dnsjava</artifactId>
<version>3.1.0</version>
</dependency>
依赖dnsjava的Base16示例:
package com.securitit.serialize.bs64;
import org.xbill.DNS.utils.base16;
public class Base16Tester {
public static void main(String[] args) throws Exception {
String plainStr = null;
String bs16Str = null;
byte[] plainBts = null;
// 原文内容.
plainStr = "Hello Base16!Now this is testing Base16!Please see the result!";
plainBts = plainStr.getBytes("UTF-8");
// Base16测试.
bs16Str = base16.toString(plainBts);
System.out.println("Base64编码结果:" + bs16Str);
plainBts = base16.fromString(bs16Str);
plainStr = new String(plainBts, "UTF-8");
System.out.println("Base64解码结果:" + plainStr);
}
}
输出结果:
Base16编码结果:48656C6C6F20426173653136EFBC814E6F7720746869732069732074657374696E6720426173653136EFBC81506C65617365207365652074686520726573756C74EFBC81
Base16解码结果:Hello Base16!Now this is testing Base16!Please see the result!
总结:
Base16与Base64优劣对比:
· Base16使用了更小的字典,Base16包含16个字符(0-9A-F),Base64包含65个字符(a-zA-Z0-9+/=或a-zA-Z0-9-_=)。
· Base16编码规则是4比特为一分组,Base64编码规则是6比特为一分组。
· 由于编码规则的不同,Base16正好可以完全切分数据,无需补位;Base64无法完全切分数据,需要使用=补位, 补位的个数在{0,1,2}范围之内。
· Base16编码后数据会膨胀一倍,Base64编码后数据会膨胀1/3。
· Base16编码后数据无特殊字符,而Base64包含特殊字符。Base64在URL传输等场景下需要尤为注意特殊字符的处理。
上一篇: AES加密过程分析