將形如 "7F3A" 的十六進位字元字串,轉換為對應的位元組陣列 {0x7F, 0x3A}。函數嚴格檢查輸入長度必為偶數、字符僅限 0-9 A-F a-f,失敗回傳 FALSE 並彈出錯誤訊息框。
// 假設 KEY_LEN 為最大輸出位元組數
#define KEY_LEN 128
BOOL TransData(CString InStr, PUCHAR OutStr)
{
UINT i = 0, j = 0;
UINT len = InStr.GetLength();
// 長度必須為偶數
if ((len % 2) != 0) {
AfxMessageBox(_T("請按要求輸入!"), _T("錯誤"), MB_OK | MB_ICONERROR);
return FALSE;
}
UCHAR Str[KEY_LEN * 2];
memset(OutStr, 0, KEY_LEN);
memset(Str, 0, KEY_LEN * 2);
// 複製字串內容到暫存緩衝區
strcpy((char*)Str, InStr.GetBuffer(0));
InStr.ReleaseBuffer();
// 字符轉數值:'0'-'9' -> 0-9, 'A'-'F' -> 10-15, 'a'-'f' -> 10-15
for (i = 0; i < len; i++) {
if (Str[i] >= '0' && Str[i] <= '9') Str[i] -= '0';
else if (Str[i] >= 'A' && Str[i] <= 'F') Str[i] -= 'A' - 10;
else if (Str[i] >= 'a' && Str[i] <= 'f') Str[i] -= 'a' - 10;
else {
AfxMessageBox(_T("數據格式錯誤!"), _T("錯誤"), MB_OK | MB_ICONERROR);
return FALSE;
}
}
// 兩兩合併為一個位元組:高 4 位 << 4 | 低 4 位
i = 0;
while (i < len) {
Str[j] = (Str[i] << 4) | Str[i + 1];
i += 2;
j++;
}
memcpy(OutStr, Str, j); // 複製 j 個位元組到輸出緩衝區
return TRUE;
}
GetBuffer/ReleaseBuffer 確保 CString 內部緩衝區可寫;memset 清零避免殘留資料。FALSE,方便調試。len/2,呼叫端需預留足夠空間 (至少 KEY_LEN)。#include <string>
#include <vector>
#include <cctype>
#include <stdexcept>
std::vector<uint8_t> HexStringToBytes(const std::string& hex)
{
if (hex.size() % 2) throw std::invalid_argument("Hex string length must be even");
std::vector<uint8_t> bytes;
bytes.reserve(hex.size() / 2);
for (size_t i = 0; i < hex.size(); i += 2) {
auto charVal = [](char c) -> uint8_t {
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
throw std::invalid_argument("Invalid hex character");
};
bytes.push_back((charVal(hex[i]) << 4) | charVal(hex[i+1]));
}
return bytes;
}
優點:無 MFC 依賴、例外處理替代訊息框、標準容器自動管理記憶體、可直接用於現代 C++ 專案。