通訊協定、加密演算法、硬體介面常需將十六進位字串(如 "7F A3 0C")轉換為位元組陣列({0x7F, 0xA3, 0x0C})。本文提供 TransData 函式,包含輸入驗證、大小寫支援、錯誤處理,回傳 BOOL 指示成敗。
BOOL TransData(const CString& inStr, PUCHAR outBuf, int maxOutLen);
inStr:輸入十六進位字串(不含空白、前綴)。outBuf:輸出緩衝區,呼叫端需保證足夠大小。maxOutLen:緩衝區最大位元組數,防止溢位。TRUE 成功,FALSE 失敗(長度非偶數、含非十六進位字元、緩衝區不足)。
BOOL TransData(const CString& inStr, PUCHAR outBuf, int maxOutLen)
{
int len = inStr.GetLength();
if (len % 2 != 0) return FALSE; // 必須成對
int outLen = len / 2;
if (outLen > maxOutLen) return FALSE;
// 暫存轉換後的 nibble 值 (0-15)
BYTE* nibbles = new BYTE[len];
for (int i = 0; i < len; ++i) {
TCHAR ch = inStr[i];
if (ch >= _T('0') && ch <= _T('9')) nibbles[i] = ch - _T('0');
else if (ch >= _T('A') && ch <= _T('F')) nibbles[i] = ch - _T('A') + 10;
else if (ch >= _T('a') && ch <= _T('f')) nibbles[i] = ch - _T('a') + 10;
else { delete[] nibbles; return FALSE; }
}
// 兩兩合併為一個位元組
for (int i = 0, j = 0; i < len; i += 2, ++j) {
outBuf[j] = (nibbles[i] << 4) | nibbles[i+1];
}
delete[] nibbles;
return TRUE;
}
CString hexStr = _T("7FA30C");
BYTE buf[16];
if (TransData(hexStr, buf, 16)) {
// buf[0]=0x7F, buf[1]=0xA3, buf[2]=0x0C
CString out;
for (int i=0; i<3; ++i) {
CString tmp; tmp.Format(_T("%02X "), buf[i]);
out += tmp;
}
TRACE(_T("Result: %s\n"), out); // 7F A3 0C
}
CString BytesToHex(const BYTE* data, int len)
{
CString str;
for (int i = 0; i < len; ++i) {
CString tmp; tmp.Format(_T("%02X"), data[i]);
str += tmp;
}
return str;
}
BOOL TransDataEx(const CString& inStr, CByteArray& outBytes)
{
CString cleaned = inStr;
cleaned.Remove(_T(' ')); cleaned.Remove(_T('\t')); cleaned.Remove(_T('\r')); cleaned.Remove(_T('\n'));
cleaned.MakeUpper();
if (cleaned.GetLength() % 2 != 0) return FALSE;
int n = cleaned.GetLength() / 2;
outBytes.SetSize(n);
for (int i = 0, j = 0; i < cleaned.GetLength(); i += 2, ++j) {
TCHAR hi = cleaned[i], lo = cleaned[i+1];
auto val = [](TCHAR c) -> BYTE {
if (c >= _T('0') && c <= _T('9')) return c - _T('0');
if (c >= _T('A') && c <= _T('F')) return c - _T('A') + 10;
return 0xFF;
};
BYTE h = val(hi), l = val(lo);
if (h == 0xFF || l == 0xFF) return FALSE;
outBytes[j] = (h << 4) | l;
}
return TRUE;
}