Home > Mobile >  C convertStringToByteArray to Delphi convertStringToByteArray
C convertStringToByteArray to Delphi convertStringToByteArray

Time:04-10

Im trying to use the GlobalPlatform library from Karsten Ohme (kaoh) in Delphi. Thanks to the help of some people here on stackoverflow i got it parially working and i am able to setup a connection to the cardreader. Now i am trying to select an AID, and therefore i need to pass the AID as array of Bytes to the function.

I use the GPShell (the commandline tool that uses the same library) source code as a reference to help me translate the functions. There i found the convertStringToByteArray function, which takes a string and converts it to a array of Bytes.

The original C function:

static int convertStringToByteArray(TCHAR *src, int destLength, BYTE *dest)
{
    TCHAR *dummy;
    unsigned int temp, i = 0;
    dummy = malloc(destLength*2*sizeof(TCHAR)   sizeof(TCHAR));
    _tcsncpy(dummy, src, destLength*2 1);
    dummy[destLength*2] = _T('\0');
    while (_stscanf(&(dummy[i*2]), _T("x"), &temp) > 0)
    {
        dest[i] = (BYTE)temp;
        i  ;
    }
    free(dummy);
    return i;
}

and i tried to write a similar procedure in Delphi, i tried to convert the string in two ways - the first (Literally) converts every character (treated as HEX) to integer. The second way uses Move:

procedure StrToByteArray(Input: AnsiString; var Bytes: array of Byte; Literally: Boolean = false);
var
  I, B : Integer;
begin
  if Literally then
  begin
    for I := 0 to Length(Input) -1 do
    if TryStrToInt('$'   Input[I  1], B) then
      Bytes[I] := Byte(B)
    else
      Bytes[I] := Byte(0);
  end else
    Move(Input[1], Bytes[0], Length(Input));
end;

But i keep getting a

(6A82: The application to be selected could not be found.)

error, when i try to select AID

A000000003000000

I know i am trying to select the right AID, because when i use this same AID with GPShell - i get a successful response. So i am not sure if the problem is in my String to Byte array procedure, or maybe somewhere else.

When i use breakpoints, and i try to convert the string to bytes literally i get

(10, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0)

in the debugger. But when i try with Move (or ORD) i get

(65, 48, 48, 48, 48, 48, 48, 48, 48, 51, 48, 48, 48, 48, 48, 48)

I also tried to convert the string to bytes online with various websites, and these give me another result

(41, 30, 30, 30, 30, 30, 30, 30, 30, 33, 30, 30, 30, 30, 30, 30)

So i am a bit lost in trying to find out what im doing wrong, is the problem in my string to bytes conversion - or do i need to look somewhere else?

CodePudding user response:

The original C code parses pairs of hex digits into bytes:

A000000003000000 -> A0 00 00 00 03 00 00 00

But your Delphi code is parsing individual hex digits into bytes instead:

A000000003000000 -> A 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0

Try this instead:

procedure StrToByteArray(Input: AnsiString; var Bytes: TBytes; Literally: Boolean = false);
var
  I, B : Integer;
begin
  if Literally then
  begin
    SetLength(Bytes, Length(Input) div 2);
    for I := 0 to Length(Bytes)-1 do
    begin
      if not TryStrToInt('$'   Copy(Input, (I*2) 1, 2), B) then
        B := 0;
      Bytes[I] := Byte(B);
    end;
  end else
  begin
    SetLength(Bytes, Length(Input));
    Move(Input[1], Bytes[0], Length(Input));
  end:
end;

That being said, Delphi has its own HexToBin() functions for parsing hex strings into byte arrays. You don't need to write your own parser, eg:

procedure StrToByteArray(Input: AnsiString; var Bytes: TBytes; Literally: Boolean = false);
begin
  if Literally then
  begin
    SetLength(Bytes, Length(Input) div 2);
    HexToBin(PAnsiChar(Input), PByte(Bytes), Length(Bytes));
  end else
  begin
    SetLength(Bytes, Length(Input));
    Move(Input[1], Bytes[0], Length(Input));
  end:
end;
  • Related