dev_tool/
hex_util.rs

1// 进制转换工具
2pub struct HexUtil;
3
4impl HexUtil {
5    /// 将字节数组转换为十六进制字符串表示
6    ///
7    /// # 参数
8    /// * `bytes` - 需要转换的字节切片
9    ///
10    /// # 返回值
11    /// 返回表示输入字节的十六进制字符串,每个字节用两个十六进制字符表示
12    pub fn to_hex(bytes: &[u8]) -> String {
13        let mut hex_str = String::new();
14        // 遍历每个字节并转换为十六进制格式
15        for byte in bytes {
16            hex_str += &format!("{:02x}", byte);
17        }
18        hex_str
19    }
20
21    /// 将字符串编码为十六进制字符串
22    ///
23    /// # 参数
24    /// * `text` - 需要编码的原始字符串
25    ///
26    /// # 返回值
27    /// 返回编码后的十六进制字符串
28    pub fn encode_hex_str(text: &str) -> String {
29        let bytes = text.as_bytes();
30        let hex_str = HexUtil::to_hex(bytes);
31        hex_str
32    }
33
34    /// 将十六进制字符串解码为UTF-8字符串
35    ///
36    /// # 参数
37    /// * `hex` - 要解码的十六进制字符串引用
38    ///
39    /// # 返回值
40    /// * `Ok(String)` - 解码成功的UTF-8字符串
41    /// * `Err(&'static str)` - 解码失败时的错误信息,可能的错误包括:
42    ///   - "Invalid hex string length":十六进制字符串长度为奇数
43    ///   - "Invalid hex digit":包含无效的十六进制字符
44    ///   - "Invalid UTF-8 sequence":解码后的字节序列不是有效的UTF-8
45    ///
46    /// # 示例
47    /// ```
48    /// let result = decode_hex_str("48656c6c6f"); // 解码为 "Hello"
49    /// ```
50    pub fn decode_hex_str(hex: &str) -> Result<String, &'static str> {
51        // 检查十六进制字符串长度是否为偶数
52        if hex.len() % 2 != 0 {
53            return Err("Invalid hex string length");
54        }
55        let mut bytes = Vec::with_capacity(hex.len() / 2);
56        let mut chars = hex.chars();
57        // 按两个字符一组解析十六进制字节
58        while let (Some(a), Some(b)) = (chars.next(), chars.next()) {
59            let byte = match u8::from_str_radix(&format!("{}{}", a, b), 16) {
60                Ok(byte) => byte,
61                Err(_) => return Err("Invalid hex digit"),
62            };
63            bytes.push(byte);
64        }
65        // 将字节序列转换为UTF-8字符串
66        match str::from_utf8(&bytes) {
67            Ok(s) => Ok(s.to_string()),
68            Err(_) => Err("Invalid UTF - 8 sequence"),
69        }
70    }
71}
72
73#[cfg(test)]
74mod tests {
75
76    use super::*;
77
78    #[test]
79    fn test_to_hex() {
80        let hex_str = HexUtil::to_hex(&[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
81        println!("{}", hex_str);
82
83        let bytes: Vec<u8> = "hello, rust!".bytes().collect();
84        let hex_str = HexUtil::to_hex(&bytes);
85        println!("{}", hex_str);
86
87        let bytes = "hello, rust!".to_string().as_bytes().to_vec();
88        let hex_str = HexUtil::to_hex(&bytes);
89        println!("{}", hex_str);
90
91        let str = String::from("hello, rust!");
92        let bytes = str.as_bytes();
93        let hex_str = HexUtil::to_hex(bytes);
94        println!("{}", hex_str);
95    }
96
97    #[test]
98    fn test_encode_decode_hex_str() {
99        let origin = "hello, rust!";
100
101        let hex_str = HexUtil::encode_hex_str(origin);
102        println!("{}", hex_str);
103        let decoded = HexUtil::decode_hex_str(&hex_str).unwrap();
104        println!("{}", decoded);
105        assert_eq!(origin, decoded);
106    }
107}