3

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.

4
  • 1
    Why are you converting to hex? Commented Nov 22, 2011 at 20:15
  • I'm converting to hex because I assumed that would be easiest for non-unicode aware applications to potentially read this 'string' (stored in a DB). I may be wrong in this assumption. Commented Nov 22, 2011 at 20:32
  • 1
    Base64 is a common choice. However, why not use UTF8? Commented Nov 22, 2011 at 20:35
  • 3
    Mick, non-Unicode-aware programs can indeed read the string, but they'll get content that they're not prepared to do anything with. Just as your program doesn't automatically handle text in this hex format, those other programs won't, either. A better encoding would be UTF-8; then all the ASCII text characters, and a number of other Latin characters, will continue to look like text. Characters from other alphabets won't transfer so well, but at least a lot of text algorithms will still work. The bottom line is to use an encoding that other programs are likely to use. Commented Nov 22, 2011 at 20:39

2 Answers 2

7

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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; 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.