C++ convertStringToByteArray 到 Delphi convertStringToByteArray

C++ convertStringToByteArray to Delphi convertStringToByteArray

我正在尝试在 Delphi 中使用来自 Karsten Ohme (kaoh) 的 GlobalPlatform library。感谢这里一些人在 Whosebug 上的帮助,我让它部分工作了,我能够建立与读卡器的连接。现在我正在尝试 select 一个 AID,因此我需要将 AID 作为字节数组传递给函数。

我使用GPSshell(使用相同库的命令行工具)源代码作为参考来帮助我翻译函数。在那里我找到了 convertStringToByteArray 函数,它接受一个字符串并将其转换为一个字节数组。

原始C++函数:

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('[=11=]');
    while (_stscanf(&(dummy[i*2]), _T("%02x"), &temp) > 0)
    {
        dest[i] = (BYTE)temp;
        i++;
    }
    free(dummy);
    return i;
}

并且我尝试在 Delphi 中编写类似的过程,我尝试以两种方式转换字符串 - 第一种(从字面上)将每个字符(视为 HEX)转换为整数。第二种方式使用 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;

但我一直收到

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

错误,当我尝试 select AID

A000000003000000

我知道我正在尝试 select 正确的 AID,因为当我将同一个 AID 与 GPSshell 一起使用时 - 我得到了成功的响应。所以我不确定问题是在我的字符串到字节数组过程中,还是在其他地方。

当我使用断点时,我尝试将字符串按字面意思转换为字节,我得到

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

在调试器中。但是当我尝试使用 Move(或 ORD)时,我得到

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

我也尝试在各种网站上在线将字符串转换为字节,这些给了我另一个结果

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

所以我有点迷茫,试图找出我做错了什么,是我的字符串到字节转换的问题 - 或者我需要看看其他地方吗?

原始 C++ 代码将 对十六进制数字 解析为字节:

A000000003000000 -> A0 00 00 00 03 00 00 00

但是您的 Delphi 代码正在将 各个十六进制数字 解析为字节:

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

试试这个:

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;

也就是说,Delphi 有自己的 HexToBin() 函数,用于将十六进制字符串解析为字节数组。您不需要编写自己的解析器,例如:

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;