将多字节十六进制转换回 UTF-8 字符串

Convert multibyte hex back to UTF-8 string

在Delphi 10.4中,我有一个字符串的十六进制表示:

function TForm1.Button2Click(Sender: TObject);
var
  i, nr : integer;
  Input, HexStr, h: String;
begin
  HexStr := '';
  Input := Edit2.Text;
  for i:=1 to Length(Input) do begin
    nr := Ord(Input[i]);
    h := IntToHex(nr, 0);
    if Length(h) = 1 then
      h := '0' + h;
    HexStr := HexStr + h;
  end;
  Edit3.Text := HexStr;
end;

对于“abc€”,我在这里得到“61626320AC”。请注意,€ 符号会转换为“20AC”。 现在为了将它转换回普通字符串,我将该十六进制拆分为 2 个字符对,使用 StrToInt() 和 '$' 前缀。我没有指示 € 符号长 4 个字符,而不是 2 个字符,这打破了欧元符号:

如何在不破坏多字节字符的情况下转换回这样的十六进制字符串?

I have no indicator for it being 4 chars long for an € sign, instead of 2 chars

仅仅因为这个原因,您根本无法将 "61626320AC" 转换回 "abc€",因为您不知道哪些十六进制代码是 2 位数字,哪些是 4 位数字数字,你没有删除它们。例如,十六进制代码 61626263 也代表有效的 Unicode 字符。

正如@TomBrunberg 在评论中提到的,您可以为每个字符使用 4 位十六进制代码,例如:

function TForm1.Button2Click(Sender: TObject);
var
  i, nr : integer;
  Input, HexStr, h: String;
begin
  HexStr := '';
  Input := Edit2.Text;
  for i := Low(Input) to High(Input) do begin
    nr := Ord(Input[i]);
    h := IntToHex(nr, 4);
    HexStr := HexStr + h;
  end;
  Edit3.Text := HexStr;
end;

然后你可以通过在调用StrToInt()时将十六进制字符串分成4个字符的组来转换回来,例如:

function TForm1.Button3Click(Sender: TObject);
var
  i, nr : integer;
  Output, HexStr, h: String;
begin
  HexStr := Edit3.Text;
  Output := '';
  i := Low(HexStr);
  while i <= High(HexStr) do begin
    h := Copy(HexStr, i, 4);
    nr := StrToInt('$' + h);
    Output := Output + Char(nr);
    Inc(i, 4);
  end;
  Edit2.Text := Output;
end;

或者,正如@AmigoJack 所暗示的,您可以改用 UTF-8,例如:

function TForm1.Button2Click(Sender: TObject);
var
  i, nr : integer;
  HexStr, h: String;
  Input: UTF8String;
begin
  HexStr := '';
  Input := UTF8String(Edit2.Text);
  for i := Low(Input) to High(Input) do begin
    nr := Ord(Input[i]);
    h := IntToHex(nr, 2);
    HexStr := HexStr + h;
  end;
  Edit3.Text := HexStr;
end;

function TForm1.Button3Click(Sender: TObject);
var
  i, nr : integer;
  HexStr, h: String;
  Output: UTF8String;
begin
  HexStr := Edit3.Text;
  Output := '';
  i := Low(HexStr);
  while i <= High(HexStr) do begin
    h := Copy(HexStr, i, 2);
    nr := StrToInt('$' + h);
    Output := Output + AnsiChar(nr);
    Inc(i, 2);
  end;
  Edit2.Text := string(Output);
end;