karmacomposer
karmacomposer

Reputation: 49

In Delphi, how do you use BinToHex?

Coming from LCL and Lazarus Pascal, I am trying to convert all my code to Delphi Pascal.

One line that is not working involves BinToHex:

function BinStr2Hex(S: AnsiString): AnsiString;
var
  i: integer;
begin
  Result := '';
  for i := 1 to Length(S)
    do Result := Result + AnsiLowerCase(BinToHex(Bytes(S[i]), 2));
end;

That throws an error of undeclared identifier Bytes (not sure how to write that as a declaration?) or do I have to use TBytes instead?

If I change it to TBytes, then I get a different error - There is no overloaded version of 'BixToHex' that can be called with these arguments.

How would I write this correctly in Delphi 10.4?

Thank you.

Upvotes: 0

Views: 1184

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 597186

There is no version of Classes.BinToHex(), in either Delphi or FreePascal, that takes 2 parameters, or has a return value. Not only that, but the buffer size passed in is the binary bye count, not the hex character count, so it makes no sense to pass in 2 when hex-encoding a single AnsiChar. So, the FreePascal code you have shown must be using a custom overload of BinToHex().

In any case, any of the following overloads of Classes.BinToHex() can be used to hex-encode an AnsiString in Delphi:

procedure BinToHex(Buffer: PAnsiChar; Text: PWideChar; BufSize: Integer); overload;
procedure BinToHex(Buffer: PAnsiChar; Text: PAnsiChar; BufSize: Integer); overload;
procedure BinToHex(var Buffer; Text: PWideChar; BufSize: Integer); overload; inline;
procedure BinToHex(var Buffer; Text: PAnsiChar; BufSize: Integer); overload; inline;
procedure BinToHex(Buffer: Pointer; Text: PWideChar; BufSize: Integer); overload; inline;
procedure BinToHex(Buffer: Pointer; Text: PAnsiChar; BufSize: Integer); overload; inline;

For example:

uses
  System.Classes, System.AnsiStrings;

// Note: I would suggest using RawByeString instead for the input...
function BinStr2Hex(S: AnsiString{RawByteString}): AnsiString;
begin
  SetLength(Result, Length(S)*2);
  BinToHex(PAnsiChar(S), PAnsiChar(Result), Length(S));
  // or: BinToHex(S[1], PAnsiChar(Result), Length(S));
  // or: BinToHex(Pointer(S), PAnsiChar(Result), Length(S));
  Result := AnsiStrings.AnsiLowerCase(Result);
end;

Or, if you change the Result to (Unicode)String:

uses
  System.Classes, System.SysUtils;

// Note: I would suggest using RawByeString instead for the input...
function BinStr2Hex(S: AnsiString{RawByteString}): String;
begin
  SetLength(Result, Length(S)*2);
  BinToHex(PAnsiChar(S), PChar(Result), Length(S));
  // or: BinToHex(S[1], PChar(Result), Length(S));
  // or: BinToHex(Pointer(S), PChar(Result), Length(S));
  Result := SysUtils.AnsiLowerCase(Result);
end;

Upvotes: 5

Related Questions