字串與十六進位(Hex)編碼互轉是序列化、加密、通訊協定、日誌記錄常見需求。本文提供 C# 標準實作、效能優化版本、VB6 相容版本,並分析 Unicode 處理細節。
每個字元轉為 4 位元十六進位 (UTF-16 碼位)
public static class HexConverter
{
///
/// 字串編碼為十六進位字串 (每字元 4 位元,大寫)
///
public static string Encode(string input)
{
if (string.IsNullOrEmpty(input)) return string.Empty;
var sb = new StringBuilder(input.Length * 4);
foreach (char c in input)
{
sb.Append(((ushort)c).ToString("X4")); // UTF-16 碼位,固定 4 位元
}
return sb.ToString();
}
///
/// 解碼十六進位字串為原始字串
///
public static string Decode(string hex)
{
if (string.IsNullOrEmpty(hex)) return string.Empty;
if (hex.Length % 4 != 0)
throw new ArgumentException("Hex 字串長度必須為 4 的倍數");
var chars = new char[hex.Length / 4];
for (int i = 0; i < chars.Length; i++)
{
string hexChar = hex.Substring(i * 4, 4);
chars[i] = (char)ushort.Parse(hexChar, NumberStyles.HexNumber);
}
return new string(chars);
}
}
string original = "Hello 世界 123";
string encoded = HexConverter.Encode(original);
// 輸出:00480065006C006C006F00204E16754C0020003100320033
string decoded = HexConverter.Decode(encoded);
Console.WriteLine($"原始:{original}");
Console.WriteLine($"編碼:{encoded}");
Console.WriteLine($"解碼:{decoded}");
Console.WriteLine($"一致:{original == decoded}"); // True
public static class HexConverterFast
{
// 查表法:預計算 0-65535 的 Hex 字串 (約 256KB 記憶體)
private static readonly string[] _hexLookup = CreateHexLookup();
private static string[] CreateHexLookup()
{
var lookup = new string[65536];
for (int i = 0; i < 65536; i++)
lookup[i] = i.ToString("X4");
return lookup;
}
public static string EncodeFast(string input)
{
if (string.IsNullOrEmpty(input)) return string.Empty;
var sb = new StringBuilder(input.Length * 4);
foreach (char c in input)
sb.Append(_hexLookup[c]);
return sb.ToString();
}
// 解碼同樣可用查表 (byte 級別),略
}
public static class ByteArrayHexConverter
{
// 位元組陣列 → Hex (每位元組 2 位元)
public static string ToHex(byte[] bytes, bool upperCase = true)
{
if (bytes == null || bytes.Length == 0) return string.Empty;
var format = upperCase ? "X2" : "x2";
var sb = new StringBuilder(bytes.Length * 2);
foreach (byte b in bytes)
sb.Append(b.ToString(format));
return sb.ToString();
}
// Hex → 位元組陣列
public static byte[] FromHex(string hex)
{
if (string.IsNullOrEmpty(hex)) return Array.Empty();
if (hex.Length % 2 != 0) throw new ArgumentException("Hex 長度必須為偶數");
var bytes = new byte[hex.Length / 2];
for (int i = 0; i < bytes.Length; i++)
{
bytes[i] = byte.Parse(hex.Substring(i * 2, 2), NumberStyles.HexNumber);
}
return bytes;
}
// Span 版本 (.NET Core 2.1+,零配置)
public static string ToHex(ReadOnlySpan bytes) =>
bytes.Length == 0 ? string.Empty : Convert.ToHexString(bytes); // .NET 5+
public static bool TryFromHex(ReadOnlySpan hex, Span destination, out int bytesWritten) =>
Convert.TryFromHexString(hex, destination, out bytesWritten); // .NET 5+
}
VB6 字串為 ANSI (雙位元組字元集 DBCS),編碼邏輯不同:
' VB6 版本 (參考轉換)
Public Function EncodeVB6(ByVal strSource As String) As String
Dim i As Long, strReturn As String
Dim byteLow As String, byteHigh As String
For i = 1 To Len(strSource)
' 取得雙位元組字元的低/高位元組
byteLow = Right$("0" & Hex$(AscB(MidB$(strSource, i * 2 - 1, 1))), 2)
byteHigh = Right$("0" & Hex$(AscB(MidB$(strSource, i * 2, 1))), 2)
' VB6 為 Little Endian:低位元組在前
strReturn = strReturn & byteHigh & byteLow
Next
EncodeVB6 = strReturn
End Function
Public Function DecodeVB6(ByVal strDecode As String) As String
If Len(strDecode) Mod 4 <> 0 Then Err.Raise vbObjectError + 1, , "Invalid hex length"
Dim i As Long, strResult As String
For i = 1 To Len(strDecode) Step 4
Dim hexChar As String = Mid$(strDecode, i, 4)
' 高位元組在前 (Big Endian 解碼)
Dim charCode As Long = CLng("&H" & hexChar)
If charCode = 63 And hexChar <> "003F" Then Err.Raise vbObjectError + 2, , "Invalid char"
strResult = strResult & ChrW$(charCode)
Next
DecodeVB6 = strResult
End Function
public static class Vb6HexConverter
{
///
/// 相容 VB6 Encode:ANSI 字串 → Hex (Little Endian 位元組序)
///
public static string EncodeVb6Compatible(string input, Encoding encoding = null)
{
encoding ??= Encoding.GetEncoding("GB2312"); // 或 Big5, 預設中文編碼
byte[] bytes = encoding.GetBytes(input);
return ByteArrayHexConverter.ToHex(bytes);
}
///
/// 相容 VB6 Decode:Hex → ANSI 字串
///
public static string DecodeVb6Compatible(string hex, Encoding encoding = null)
{
encoding ??= Encoding.GetEncoding("GB2312");
byte[] bytes = ByteArrayHexConverter.FromHex(hex);
return encoding.GetString(bytes);
}
}
// 位元組陣列 ↔ Hex (最高效能)
string hex = Convert.ToHexString(bytes); // 編碼
bool ok = Convert.TryFromHexString(hex, out bytes); // 解碼 (不拋例外)
// 字串 ↔ UTF-8 位元組
byte[] utf8Bytes = "Hello".ToUtf8Bytes(); // 擴充方法或 Encoding.UTF8.GetBytes
選擇正確的編碼策略,能確保跨系統、跨語言、跨平台的資料完整性與互通性。