欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Base16 应用与原理解析

程序员文章站 2024-03-14 14:33:58
...

  简介:

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