C++中如何将十六进制字符串转换为uint8_t数组?
解决十六进制字符串与uint8_t数组/向量的互相转换问题
首先来处理你第一个问题:把十六进制字符串"F3D5"转换成uint8_t类型的数组。
一、十六进制字符串转uint8_t数组/向量
思路很直观:十六进制字符串里每两个字符对应一个uint8_t字节(毕竟一个uint8_t是8位,刚好覆盖两位十六进制数的0-FF范围)。这里给你两种实现方式,按需选择:
方法1:利用标准库函数快速实现
#include <string> #include <vector> #include <cstdint> #include <stdexcept> #include <cstdlib> std::vector<uint8_t> hex_string_to_uint8_vector(const std::string& hex_str) { std::vector<uint8_t> result; // 先校验字符串长度是否为偶数,避免解析出错 if (hex_str.length() % 2 != 0) { throw std::invalid_argument("十六进制字符串长度必须为偶数"); } for (size_t i = 0; i < hex_str.length(); i += 2) { // 每次截取两位字符的子串 std::string byte_substr = hex_str.substr(i, 2); // 将十六进制子串转为uint8_t uint8_t byte = static_cast<uint8_t>(std::stoul(byte_substr, nullptr, 16)); result.push_back(byte); } return result; } // 使用示例 int main() { std::string key = "F3D5"; // 先转成向量 auto key_vec = hex_string_to_uint8_vector(key); // 如果需要固定长度的数组(已知长度为2) uint8_t key_arr[2]; std::copy(key_vec.begin(), key_vec.end(), key_arr); // 此时key_arr[0] = 0xF3,key_arr[1] = 0xD5 return 0; }
方法2:手动解析字符(更高效,适合性能敏感场景)
如果不想依赖std::stoul,可以手动把十六进制字符转成数值:
#include <string> #include <vector> #include <cstdint> #include <stdexcept> uint8_t hex_char_to_byte(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return 10 + c - 'a'; if (c >= 'A' && c <= 'F') return 10 + c - 'A'; throw std::invalid_argument("包含非法的十六进制字符"); } std::vector<uint8_t> hex_string_to_uint8_vector(const std::string& hex_str) { std::vector<uint8_t> result; if (hex_str.size() % 2 != 0) { throw std::invalid_argument("十六进制字符串长度必须为偶数"); } for (size_t i = 0; i < hex_str.size(); i += 2) { uint8_t high_byte = hex_char_to_byte(hex_str[i]); uint8_t low_byte = hex_char_to_byte(hex_str[i+1]); // 拼接成一个完整的字节 result.push_back((high_byte << 4) | low_byte); } return result; }
二、uint8_t*转十六进制字符串的代码修正与实现
先指出你现有代码里的两个明显问题:
uint8_t key = generateKey();类型不匹配!generateKey()返回的是uint8_t*,你应该写成uint8_t* key = generateKey();vector<uint8_t> keyVector(begin(key), end(key));非法调用!std::begin和std::end只对数组(不是指针)、标准容器生效,指针本身不知道指向的数组长度,必须明确传入长度才能正确构造向量。
正确的代码流程
假设generateKey()会返回密钥的指针和长度(建议改成这种设计,否则无法安全处理动态分配的内存):
#include <string> #include <vector> #include <cstdint> #include <sstream> #include <iomanip> // 调整generateKey的签名,返回指针和长度的配对 std::pair<uint8_t*, size_t> generateKey() { // 示例:生成2字节的密钥 static uint8_t key_buf[] = {0xF3, 0xD5}; return {key_buf, sizeof(key_buf)/sizeof(key_buf[0])}; } // 实现uint8向量转十六进制字符串的函数 std::string uint8_vector_to_hex_string(const std::vector<uint8_t>& vec) { std::stringstream ss; ss << std::hex << std::setfill('0'); // 如果需要大写的十六进制字符,加一句ss << std::uppercase; for (uint8_t byte : vec) { // 每个字节输出两位十六进制数 ss << std::setw(2) << static_cast<int>(byte); } return ss.str(); } // 使用示例 int main() { auto [key_ptr, key_len] = generateKey(); // C++17结构化绑定,旧标准可以用key_ptr = generateKey().first; std::vector<uint8_t> keyVector(key_ptr, key_ptr + key_len); std::string hexadecimalKey = uint8_vector_to_hex_string(keyVector); // 此时hexadecimalKey的值是"f3d5"(小写)或"F3D5"(大写) return 0; }
如果generateKey()无法修改返回值,那你必须提前知道密钥的固定长度,比如密钥是2字节,就写成std::vector<uint8_t> keyVector(key, key + 2);。
内容的提问来源于stack exchange,提问作者Elie Daher
相关产品推荐
相关产品推荐

