Mick
Mick

Reputation: 13495

With Delphi 2010, how can I convert a Unicode string to a hexadecimal string, and back?

I am using Delphi 2010 and I have a need to be able to convert a string to a hexadecimal string, and then later be able to convert that hexadecimal string back to the original unicode string.

For example, my string is: Михаи́л Васи́льевич Ломоно́сов

I was able to use Warren P's StringToHex16 snippet here (and I pasted Warren's snippet below) to convert the string to a hex string, but I don't know how to convert that hex string back to the original unicode string.

function StringToHex16(str: string): string;
var
   i:integer;
   s:string;
begin
       s:='';

       for i:=1 to length(str) do begin
           s:=s+inttohex(Integer(str[i]),4);
       end;
       result:=s;

end;

Using the linked StringToHex16 gives me this hex string:

041C04380445043004380301043B002004120430044104380301043B044C04350432043804470020041B043E043C043E043D043E03010441043E0432

I am a bit naive with this topic and I would appreciate any help you can provide to convert this hex string back to the original input.

Upvotes: 3

Views: 3399

Answers (2)

Rob Kennedy
Rob Kennedy

Reputation: 163357

The linked function produces four hexadecimal digits for each character in the input string, so your inverse function needs to take blocks of four characters and convert them into one. The function used IntToHex to convert the numeric character codes of the input string into the output characters, and the inverse of IntToHex is StrToInt with the hex prefix, so let's use that.

function HexToString16(const str: string): string;
var
  i: Integer;
  code: string;
begin
  Result := '';
  i := 1;
  while i < Length(str) do begin
    code := Copy(str, i, 4);
    Result := Result + Chr(StrToInt('$' + code));
    Inc(i, 4);
  end;
end;

This function assumes the input was generated by StringToHex16 or something equivalent. If it doesn't consist of a multiple of four hexadecimal digits, behavior is undefined.

Upvotes: 7

az01
az01

Reputation: 2028

I have this working function, if you like. It's not Unicode-aware. It can be easily modified to return a chunk

Function HexStringToBytes(Const Value: String): TBytes;
Var
  i, v: Integer;
  dg0, dg1: Byte;
  HexStr: String;
Begin
  HexStr := '';
  For i:= 1 To Length(Value) Do If Value[i] <> #32 Then HexStr := HexStr + Value[i];
  SetLength( Result, Length(HexStr) Div 2 );
  For i:= 1 To Length(HexStr) Div 2 Do
    Begin
      dg0 := 0;
      dg1 := 1;
      If TryStrToInt( '$' + HexStr[i*2 -1], v ) Then dg0 := Byte(v) Shl 4;
      If TryStrToInt( '$' + HexStr[i*2], v )    Then dg1 := Byte(v);
      Result[i-1] := dg0 + dg1;
    End;
End;

Upvotes: 0

Related Questions