天天看点

按TLV格式拆分APDU指令

判断规则:

     1、Tag第一字节的bit3为1,则该tag为模版;

     2、Tag第一字节高5位为全1,则该Tag的长度为2字节,否则则为1字节长度。

SerchTagFromDGIData(char *inData, char *tag, char *outV, char *outTLV)

{

 int tag_len = 0;

 CString _inData = "", _tag = "";

 char _outV[256], _outTLV[256];

 memset(_outV, 0x00, sizeof(_outV));

 memset(_outTLV, 0x00, sizeof(_outTLV));

 _inData.Format("%s", inData);

 _tag.Format("%s", tag);

 while(_inData != "")

 {

  CString tag_TLV = "", tag_V = "";

  int iTemp = strtol(_inData.Left(2), NULL, 16);

  if ((iTemp & 0x20) == 0x20)  //是模板

  {

   if ((iTemp & 0x1F) == 0x1F) //Tag长度2字节

   {

    tag_len = 4;

   }

   else  //Tag长度1字节

   {

    tag_len = 2;

   }

   int v_len = strtol(_inData.Mid(tag_len, 2), NULL, 16);

   //判断长度是否添加81,即长度最高位是否为1

   if ((v_len & 0x80) == 0x80)

   {

    v_len = strtol(_inData.Mid(tag_len + 2, 2), NULL, 16);

    tag_TLV = _inData.Mid(0, v_len * 2 + tag_len + 4);

    tag_V = _inData.Mid(tag_len + 4, v_len * 2);

   }

   else

   {

    tag_TLV = _inData.Mid(0, v_len * 2 + tag_len + 2);

    tag_V = _inData.Mid(tag_len + 2, v_len * 2);

   }

   _inData = tag_V;

  }

  else  //不是模板

  {

   if ((iTemp & 0x1F) == 0x1F) //

   {

    tag_len = 4;

   }

   else

   {

    tag_len = 2;

   }

   int v_len = strtol(_inData.Mid(tag_len, 2), NULL, 16);

   //判断长度是否添加81,即长度最高位是否为1

   if ((v_len & 0x80) == 0x80)

   {

    v_len = strtol(_inData.Mid(tag_len+2, 2), NULL, 16);

    tag_TLV = _inData.Mid(0, v_len * 2 + tag_len + 4);

    tag_V = _inData.Mid(tag_len + 4, v_len *2);

   }

   else

   {

    tag_TLV = _inData.Mid(0, v_len * 2 + tag_len + 2);

    tag_V = _inData.Mid(tag_len + 2, v_len * 2);

   }

   _inData = _inData.Mid(tag_TLV.GetLength(), _inData.GetLength() - tag_TLV.GetLength());

  }

  if (_tag == tag_TLV.Mid(0, tag_len))

  {

   sprintf(_outV, "%s", tag_V);

   sprintf(_outTLV, "%s", tag_TLV);

   memcpy(outV, _outV, strlen(_outV));

   memcpy(outTLV, _outTLV, strlen(_outTLV));

   break;

  }

 }

}



继续阅读