Arduino:uint8_t数组到字符串

时间:2013-11-26 01:47:58

标签: android arduino nfc apdu hce

我有一个基于android的NFC应用程序,它发送哈希作为apdu答案。这是我在Android应用中用来发送哈希的代码:

@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 !!!

2 个答案:

答案 0 :(得分: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也为空。 Le编码预期作为响应的字节数(特殊情况Le = 0x00,这意味着预期256个响应字节。

    响应APDU(您发送的内容为processCommandApdu 中的返回值)如下所示:

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

    DATA是响应数据。 SW1&amp; SW2形成响应状态字(通常SW1 = 0x90,SW2 = 0x00表示成功)。请注意,SW1和SW2是强制性的。

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

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

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

答案 1 :(得分:-1)

好的,所以我想出了答案。我不需要itoa。我可以将RAW输入强制转换为char并得到我需要的东西:

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

            Serial.println(" ");

这就是结果:

e68d3f574009cbbe0111502ÿÿÿÿÿÿÿÿÿ

现在我想知道为什么最后9个字符被替换为255?