1-Hex编码
发布时间:2023-02-16 13:47:44 所属栏目:Java 来源:互联网
导读:编码原理 Hex编码就是把一个8位的字节数据用两个十六进制数展示出来,编码时,将8位二进制码重新分组成两个4位的字节,其中一个字节的低4位是原字节的高四位,另一个字节的低4位是原数据的低4位,高4位都补0,然后输出这两个字节对应十六进制数字作为编码。H
编码原理 Hex编码就是把一个8位的字节数据用两个十六进制数展示出来,编码时,将8位二进制码重新分组成两个4位的字节,其中一个字节的低4位是原字节的高四位,另一个字节的低4位是原数据的低4位,高4位都补0,然后输出这两个字节对应十六进制数字作为编码。Hex编码后的长度是源数据的2倍,Hex编码的编码表为 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 a 11 b 12 c 13 d 14 e 15 f 比如ASCII码A的Hex编码过程为 ASCII码:A (65) 二进制码:0100_0001 重新分组:0000_0100 0000_0001 十六进制: 4 1 Hex编码:41 丁 e4b881 代码实现 使用Bouncy Castle的实现 下面的代码使用开源软件Bouncy Castle实现Hex编解码,使用的版本是1.56。 import java.io.UnsupportedEncodingException; import org.bouncycastle.util.encoders.Hex; public class HexTestBC { public static void main(String[] args) throws UnsupportedEncodingException { // 编码 byte data[] = "A".getBytes("UTF-8"); byte[] encodeData = Hex.encode(data); String encodeStr = Hex.toHexString(data); System.out.println(new String(encodeData,"UTF-8")); System.out.println(encodeStr); // 解码 byte[] decodeData = Hex.decode(encodeData); byte[] decodeData2 = Hex.decode(encodeStr); System.out.println(new String(decodeData,"UTF-8")); System.out.println(new String(decodeData2,"UTF-8")); } } 程序输出 41 41 A A 使用Apache Commons Codec实现 下面的代码使用开源软件Apache Commons Codec实现Hex编解码,使用的版本是1.10。 import java.io.UnsupportedEncodingException; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; public class HexTestCC { public static void main(String[] args) throws UnsupportedEncodingException,DecoderException { // 编码 byte data[] = "A".getBytes("UTF-8"); char[] encodeData = Hex.encodeHex(data); String encodeStr = Hex.encodeHexString(data); System.out.println(new String(encodeData)); System.out.println(encodeStr); // 解码 byte[] decodeData = Hex.decodeHex(encodeData); System.out.println(new String(decodeData,"UTF-8")); } } 源码分析 Bouncy Castle实现源码分析 Bouncy Castle实现Hex编解码的是org.bouncycastle.util.encoders.HexEncoder类,实现编码时首先定义了一个编码表 protected final byte[] encodingTable = { (byte)'0',(byte)'1',(byte)'2',(byte)'3',(byte)'4',(byte)'5',(byte)'6',(byte)'7',(byte)'8',(byte)'9',(byte)'a',(byte)'b',(byte)'c',(byte)'d',(byte)'e',(byte)'f' }; 然后编码的代码是 public int encode( byte[] data,int off,int length,OutputStream out) throws IOException { for (int i = off; i < (off + length); i++) { int v = data[i] & 0xff; out.write(encodingTable[(v >>> 4)]); out.write(encodingTable[v & 0xf]); } return length * 2; } 解码的实现稍微复杂一点,在HexEncoder的构造方法中会调用initialiseDecodingTable建立解码表,代码如下 protected final byte[] decodingTable = new byte[128]; protected void initialiseDecodingTable() { for (int i = 0; i < decodingTable.length; i++) { decodingTable[i] = (byte)0xff; } for (int i = 0; i < encodingTable.length; i++) { decodingTable[encodingTable[i]] = (byte)i; } decodingTable['A'] = decodingTable['a']; decodingTable['B'] = decodingTable['b']; decodingTable['C'] = decodingTable['c']; decodingTable['D'] = decodingTable['d']; decodingTable['E'] = decodingTable['e']; decodingTable['F'] = decodingTable['f']; } 解码表是一个长度是128的字节数组,每个位置代表对应的ASCII码,该位置上的值表示该ASCII码对应的二进制码。具体到Hex的解码表,第48-59个位置,即ASCII码0-9的位置保存了数字0-9,第65-70个位置,即ASCII码A-F的位置保存了数字10-15,第97-102个位置,即ASCII码a-f同样保存了数字10-15。解码表为 比如array[65] = A -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 (编辑:甘南站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |