2013-11-26 208 views
0

我有一个构建在android上的NFC应用程序,它发送一个散列作为apdu答案。这是我在我的Android应用程序中使用的代码发送哈希:Arduino:uint8_t数组到字符串

@Override 
    public byte[] processCommandApdu(byte[] arg0, Bundle arg1) { 

     String hash = "e68d3f574009cbbe011150263634c5c0"; 

     return hash.getBytes(Charset.forName("UTF-8")); 

    } 

现在,当我收到它的东西Arduino的身边,我得到这个RAW数据:

10154561005110253555248485799989810148494949534850255255255255255255255255255 

如何获得从那回来的散列?

这就是我现在所拥有的,但它显然不是工作:

 uint8_t response[32]; 

     uint8_t responseLength = sizeof(response); 

     if (nfc.inDataExchange(message, sizeof(message), response, &responseLength)) { 

      Serial.print("RAW: "); 
      for (int i = 0; i < sizeof(response); i++) { 
       Serial.print(response[i]); 
      } 

      Serial.println(" "); 

      char buffer[32]; 
      itoa((int)response,buffer,8); 

      Serial.print("ITOA: "); 
      for (int i = 0; i < sizeof(buffer); i++) { 
       Serial.print(buffer[i]); 
      } 

      Serial.println(" "); 
     } 

这是上面的代码的串行输出:

RAW: 10154561005110253555248485799989810148494949534850255255255255255255255255255 
ITOA: 4253 µ  + 
    3ü  R  

HALP!

回答

1

三点建议,虽然他们没有真正解释了为什么最后几个字节被截断:

  1. 不要十六进制哈希表示形式转换为字符串后面的UTF-8编码发送这些字符。这将是更有效(和更少的解码努力)直接发送哈希作为一个字节:

    @Override 
    public byte[] processCommandApdu(byte[] arg0, Bundle arg1) { 
        byte[] hash = { 
          (byte)0xe6, (byte)0x8d, (byte)0x3f, (byte)0x57, 
          (byte)0x40, (byte)0x09, (byte)0xcb, (byte)0xbe, 
          (byte)0x01, (byte)0x11, (byte)0x50, (byte)0x26, 
          (byte)0x36, (byte)0x34, (byte)0xc5, (byte)0xc0 
        }; 
    
        return hash; 
    } 
    

    如果你已经有了哈希作为十六进制字符串,我建议你把它转换成其字节表示对Android第一方。

  2. 使用HCE时,应遵守ISO/IEC 7816-4 APDU,而不是仅发送随机数据。命令APDU(短格式)由以下组成:

    +----------+----------+----------+----------+----------+------------+----------+ 
    | CLA  | INS  | P1  | P2  | Lc  | DATA  | Le  | 
    | (1 Byte) | (1 Byte) | (1 Byte) | (1 Byte) | (1 Byte) | (Lc Bytes) | (1 Byte) | 
    +----------+----------+----------+----------+----------+------------+----------+ 
    

    其中Lc编码DATA的字节数。如果DATA为空,则Lc也是空的。乐编码(预期为响应字节数与乐= 0×00,这意味着预期的256个响应字节的特殊情况。

    的响应APDU(这就是你发在processCommandApdu返回值)看起来是这样的:

    +----------+----------+----------+ 
    | DATA  | SW1  | SW2  | 
    | (n Byte) | (1 Byte) | (1 Byte) | 
    +----------+----------+----------+ 
    

    DATA是响应数据SW1 SW2 &形成响应状态字(通常SW1 = 0×90,SW2 = 0×00成功)注意,SW1和SW2是强制性的。

  3. 当通过inDataExchange响应迭代使用,而不是你的最大缓冲区长度由函数(responseLength)提供的响应长度:

    for (int i = 0; i < responseLength; ++i) { 
        ... 
    } 
    

    此外,我建议你提供一个缓冲区不是更最大预期响应长度。 (特别是在你对32字符串使用UTF-8编码的情况下,对于某些字符可能会导致多于32个字节。)

+0

谢谢。这工作。 – ReX357

-1

好吧,我想出了我的答案。我不需要itoa。我可以强制转换原始输入为char并获得我所需要的:

  Serial.print("TYPECASTED RAW: "); 
      for (int i = 0; i < sizeof(response); i++) { 
       Serial.print((char)response[i]); 
      } 

      Serial.println(" "); 

这outputed:

e68d3f574009cbbe0111502ÿÿÿÿÿÿÿÿÿ 

现在我只是想知道为什么最后9个字符被255取代?

+0

某些整数值具有特殊含义作为字符。它不应该直接翻译,除非整数是字符。 Hexidecimal以一种方式解决了这个问题,base64解决了另一个问题。 – Lodewijk