2023 第一行代码, 由于分析了一波数据包组成, 想着如何把网络数据包中的 16 进制编码转成明文, 于是有了下面的工具类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package com.gomyck.util;
import java.nio.charset.StandardCharsets;
/**
* 16进制字符串与字符串互转工具类
*
* 按字节进行 16 进制与 2 进制转换就是 一字节8位 转 两位0~F
* 每个字节分两次 从中间切割为左右各四位 转换成十六进制
* 右侧四位不需要偏移四位, 因为本身这四位就没超过16 (最大 15 2^4-1)
* 左侧四位需要向右偏移 4 位, 也就是除以 16(左侧四位肯定是 16 的倍数) 16 32 48 ....
* 然后把值 按照 0~F 从左到右拼接起来, 比如 0x12 就是 十进制的18 对应的二进制就是 0b0001 0010
* 转换关系如下:
* System.out.println((0b00010010 & 0x0f0) >> 4); //结果为1 计算左侧四位对应的 16 进制数
* System.out.println((0b00110010 & 0x0f)); //结果为2 计算右侧四位对应的 16 进制数
*
* Unicode 是咋回事儿?
* Unicode 是一种字符集, 每个字符再这个集合里, 有固定的标识(ID)
* exp: (U+0041 65:A) (U+005A 90:Z) (U+0061 97:a) (U+007A 122:z)
* 去 https://www.unicode.org/charts/ 这里可以查看
* 或 https://www.unicode.org/charts/charindex.html 搜索 chinese 可以查看中文编码表
* 实际上 Unicode 最终也会根据 16 进制的标识转换成 2 进制, 用以被计算机识别, 并最终展示到终端
* 数据与指令 - CPU(字体引擎处理, 每个字的 RGB) - 显卡驱动程序 - 显卡(GPU) - 显示器 - 人眼
*
* @author gomyck
* --------------------------------
* | qq: 474798383 |
* | email: [email protected] |
* | blog: https://blog.gomyck.com |
* --------------------------------
* @version [1.0.0]
* @since 2023/1/10
*/
public class HexUtil {
public final static String HEX_DIC = "0123456789ABCDEF";
/**
* 十六进制字符串转字符串
*
* @param hexStr 十六进制字符串
* @param delimiter 分隔符
* @return 字符串
*/
public static String hex2String(String hexStr, String delimiter) {
if (ObjectJudge.isNull(hexStr)) return null;
if (delimiter == null) delimiter = "";
hexStr = hexStr.toUpperCase();
hexStr = hexStr.replaceAll(delimiter, "");
char[] hexChars = hexStr.toCharArray();
byte[] strBytes = new byte[hexStr.length() / 2];
int hexNum;
for (int i = 0; i < strBytes.length; i++) {
hexNum = HEX_DIC.indexOf(hexChars[2 * i]) * 16;
hexNum += HEX_DIC.indexOf(hexChars[2 * i + 1]);
strBytes[i] = (byte) (hexNum & 0xff);
}
return new String(strBytes, StandardCharsets.UTF_8);
}
/**
* 字符串转换成十六进制字符串
*
* @param str 字符串
* @param delimiter 分隔符
* @return 十六进制字符串
*/
public static String string2Hex(String str, String delimiter) {
if (ObjectJudge.isNull(str)) return null;
if (ObjectJudge.isNull(delimiter)) delimiter = "";
char[] hexCharsDic = HEX_DIC.toCharArray();
StringBuilder sb = new StringBuilder();
byte[] strBytes = str.getBytes();
int hexIndex;
for (int i = 0; i < strBytes.length; i++) {
hexIndex = (strBytes[i] & 0x0f0) >> 4;
sb.append(hexCharsDic[hexIndex]);
hexIndex = strBytes[i] & 0x0f;
sb.append(hexCharsDic[hexIndex]);
if (i != strBytes.length - 1) sb.append(delimiter);
}
return sb.toString()
.trim();
}
}