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传输等场景下需要尤为注意特殊字符的处理。

猜你喜欢

转载自blog.csdn.net/securitit/article/details/106934357