如何从含字符串消息的vector<uint8_t>中提取指定十六进制数据?
问题描述
需要从存储着vector<string>内容的vector<uint8_t>中提取十六进制数据。原本直接从vector<string>提取更简便,但目前数据仅存在于vector<uint8_t>中。尝试用std::search函数查找模式0x88 0x66未生效,运行代码时输出“Pattern '0x88 0x66 not found.'”,求解决办法。
现有代码
#include <iostream> #include <vector> #include <string> #include <sstream> #include <iomanip> #include <algorithm> int main() { std::vector<std::string> messages = { "67 odd=123; time=0; hex=0x88 0x66 0x2d 0x20 0x10 0x11", "65 odd=123; time=0; hex=0x88 0x66 0x4e 0x30 0x10 0x11" }; std::vector<uint8_t> byteVector; for (const std::string& message: messages) { byteVector.insert(byteVector.end(), message.begin(), message.end()); } // Search for the pattern "0x88 0x66" in byteVector std::vector<uint8_t> pattern = {0x88, 0x66}; auto it = std::search(byteVector.begin(), byteVector.end(), pattern.begin(), pattern.end()); if (it != byteVector.end()) { while (it != byteVector.end()) { for (size_t i = 0; i < pattern.size(); ++i) { std::cout << std::hex << "0x" << std::setw(2) << std::setfill('0') << static_cast<int>(*(it + i)) << " "; } std::cout << std::endl; // Move to the next occurrence of the pattern it = std::search(it + 1, byteVector.end(), pattern.begin(), pattern.end()); } } else { std::cout << "Pattern '0x88 0x66 not found.'" << std::endl; } return 0; }
问题原因
你当前的byteVector里存储的是字符串的ASCII字符,而非十六进制字符串对应的实际字节值。比如原字符串中的"0x88"被拆成了'0'(0x30)、'x'(0x78)、'8'(0x38)、'8'(0x38)这四个字节,而不是单个字节0x88。因此用{0x88, 0x66}作为搜索模式,自然找不到匹配项。
解决方案
正确的做法是先从vector<uint8_t>中解析出hex=字段后的十六进制字符串,将其转换为实际的uint8_t字节,再进行搜索。以下是修正后的代码:
#include <iostream> #include <vector> #include <string> #include <sstream> #include <iomanip> #include <algorithm> #include <cctype> // 从ASCII字符的vector中提取hex字段并转换为字节vector std::vector<uint8_t> parseHexFromByteVector(const std::vector<uint8_t>& byteVec) { std::vector<uint8_t> result; std::string tempStr(byteVec.begin(), byteVec.end()); std::istringstream iss(tempStr); std::string token; // 找到hex=开头的部分 while (std::getline(iss, token, ';')) { size_t hexPos = token.find("hex="); if (hexPos != std::string::npos) { std::string hexPart = token.substr(hexPos + 4); std::istringstream hexIss(hexPart); std::string hexByteStr; while (hexIss >> hexByteStr) { // 去掉0x前缀,转换为uint8_t if (hexByteStr.substr(0,2) == "0x") { hexByteStr = hexByteStr.substr(2); } uint8_t byte = static_cast<uint8_t>(std::stoul(hexByteStr, nullptr, 16)); result.push_back(byte); } } } return result; } int main() { std::vector<std::string> messages = { "67 odd=123; time=0; hex=0x88 0x66 0x2d 0x20 0x10 0x11", "65 odd=123; time=0; hex=0x88 0x66 0x4e 0x30 0x10 0x11" }; std::vector<uint8_t> byteVector; for (const std::string& message: messages) { byteVector.insert(byteVector.end(), message.begin(), message.end()); } // 先解析出实际的十六进制字节 std::vector<uint8_t> actualBytes = parseHexFromByteVector(byteVector); // 搜索目标模式 std::vector<uint8_t> pattern = {0x88, 0x66}; auto it = std::search(actualBytes.begin(), actualBytes.end(), pattern.begin(), pattern.end()); if (it != actualBytes.end()) { while (it != actualBytes.end()) { for (size_t i = 0; i < pattern.size(); ++i) { std::cout << std::hex << "0x" << std::setw(2) << std::setfill('0') << static_cast<int>(*(it + i)) << " "; } std::cout << std::endl; // 查找下一个匹配项 it = std::search(it + 1, actualBytes.end(), pattern.begin(), pattern.end()); } } else { std::cout << "Pattern '0x88 0x66 not found.'" << std::endl; } return 0; }
代码说明
parseHexFromByteVector函数将vector<uint8_t>转换为字符串,从中提取hex=后的内容,逐个将十六进制字符串(如"0x88")转换为实际的uint8_t字节。- 之后用转换得到的实际字节vector进行搜索,就能正确匹配到
0x88 0x66模式。 - 运行修正后的代码会输出两次
0x88 0x66,对应原两个字符串中的匹配项。
内容的提问来源于stack exchange,提问作者Bebe
相关产品推荐
相关产品推荐

