使用 Arduino 解码较大的 DES 数据失败
Decoding a larger DES data fails with Arduino
我正在尝试将 NODE_MCU_V3 添加到我有 运行 Raspberry 和 Java 库的小型 BMS 系统。
设备调用服务器,并得到 JSON 响应。此响应经过 DES 加密,然后进行 Base64 编码。信息的发送与编码配合得很好,而接收响应则适用于较小的响应。但如果 JSON 超过 208 个字符,则解密失败。我对 Arduino 和 C 不太熟悉,但我猜它与尺寸有关。
这是相关代码。结果是从服务器响应中获取的字符串。
Base64 解码器的结果是预期的,问题出在 DES 解码器上。我在 HEX 的底部添加了示例。
char encoded[result.length()];
result.toCharArray(encoded, result.length());
// Convert back.
int decodedLength = Base64.decodedLength(encoded, sizeof(encoded));
char decodedChar[decodedLength];
Base64.decode(decodedChar, encoded, sizeof(encoded));
Serial.print("Decoded: "); printArray((byte*) decodedChar, sizeof(decodedChar));
byte jsonByte[decodedLength];
for (int i = 0; i < (des.get_size() / 8); i++) {
byte intermitInput[8];
byte intermitResult[8];
for (int j = 0; j < 8; j++) {
intermitInput[j] = (byte) decodedChar[(i * 8) + j];
}
des.decrypt(intermitResult, intermitInput, key);
for (int j = 0; j < 8; j++) {
jsonByte[(i * 8) + j] = intermitResult[j];
}
}
Serial.print("Decrypted: "); printArray(jsonByte, sizeof(jsonByte));
char json[sizeof(jsonByte) + 1];
for (int i = 0; i < sizeof(jsonByte); i++) {
json[i] = (char)jsonByte[i];
}
json[sizeof(jsonByte)] = '[=10=]';
Serial.print("Decripted result:\t");
Serial.println(json);
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, json);
// Test if parsing succeeds.
if (error) {
Serial.print(F("deserializeJson() failed."));
return;
}
const char* resultStatus = doc["result"];
if (strstr(resultStatus, "SUCCESS") < 0) {
Serial.print("Problem with the response: "); Serial.println(resultStatus);
return;
}
Serial.print(" Value: "); Serial.println(resultStatus);
服务器:
Json - Datalength: 359 - {"result":"SUCCESS","message":"(none)", "actions":[{"action":"initiation","data":[{"type":"IO_CONTROLLER","inputPins":"","outputPinsManual":"","relayDefaultState":"","inputResistance":"","inputPinsManual":"","outputPins":"4"}], "hostname":"AR-259bfc91250", "macAddress":"null"},{"action":"campAlarm","value":"false"},{"action":"warningBeep","value":"false"}]}
Clear JSON HEX: 7b22726573756c74223a2253554343455353222c226d657373616765223a22286e6f6e6529222c2022616374696f6e73223a5b7b22616374696f6e223a22696e6974696174696f6e222c2264617461223a5b7b2274797065223a22494f5f434f4e54524f4c4c4552222c22696e70757450696e73223a22222c226f757470757450696e734d616e75616c223a22222c2272656c617944656661756c745374617465223a22222c22696e707574526573697374616e6365223a22222c22696e70757450696e734d616e75616c223a22222c226f757470757450696e73223a2234227d5d2c2022686f73746e616d65223a2241522d3235396266633931323530222c20226d616341646472657373223a226e756c6c227d2c7b22616374696f6e223a2263616d70416c61726d222c2276616c7565223a2266616c7365227d2c7b22616374696f6e223a227761726e696e6742656570222c2276616c7565223a2266616c7365227d5d7d
Encrypted before Base64: 1e64fd8c074b2eda044f2ed820dab06949e5a2c5602918b13779e906c2733c1719965a456e2127fef0c910cbbbfcd137c535c9423cc14e7e8497de8fd340441f0a48634ccaa6d64e5d23bd2bc4f06d3998adc310f77631d17478f8c85168663e9ecba5551d1bac0c06b26e778a96e4292de903683e4fadeb5c94050f7b30aa1de5a11408a366bef1584115b530ea4b9efffcc0abef06ed6b0baca92b67ef54587eaa0e71976261eacf7942ec2a566d962246ebf7aeacda6d4a6b5246ca2281cf1e6db1af905a5260c74276ba7bcbba00e4ce82abb260f606afee1277f7cbf42ab3cac3cc09c5fb9676c5feb30c47dcd437d64a7886376435eeee517e14673b45ead6ddf30b238e46c53f6bbbedbab1e74ca1fbb5dbac628a12ae007471017d969757d37a2ffa5f992c5ecc9c9fad3f500638b7a135695eba21b54947a3492fdc98b3a2570fbea4bae0d50d426152ee8012779de0f5ba9e96ae15cef583353a3116499bea9e766488
Base64 send: HmT9jAdLLtoETy7YINqwaUnlosVgKRixN3npBsJzPBcZllpFbiEn/vDJEMu7/NE3xTXJQjzBTn6El96P00BEHwpIY0zKptZOXSO9K8TwbTmYrcMQ93Yx0XR4+MhRaGY+nsulVR0brAwGsm53ipbkKS3pA2g+T63rXJQFD3swqh3loRQIo2a+8VhBFbUw6kue//zAq+8G7WsLrKkrZ+9UWH6qDnGXYmHqz3lC7CpWbZYiRuv3rqzabUprUkbKIoHPHm2xr5BaUmDHQna6e8u6AOTOgquyYPYGr+4Sd/fL9CqzysPMCcX7lnbF/rMMR9zUN9ZKeIY3ZDXu7lF+FGc7RerW3fMLI45GxT9ru+26sedMofu126xiihKuAHRxAX2Wl1fTei/6X5ksXsycn60/UAY4t6E1aV66IbVJR6NJL9yYs6JXD76kuuDVDUJhUu6AEned4PW6npauFc71gzU6MRZJm+qedmSI
Arduino:
Base64 coming in: HmT9jAdLLtoETy7YINqwaUnlosVgKRixN3npBsJzPBcZllpFbiEn/vDJEMu7/NE3xTXJQjzBTn6El96P00BEHwpIY0zKptZOXSO9K8TwbTmYrcMQ93Yx0XR4+MhRaGY+nsulVR0brAwGsm53ipbkKS3pA2g+T63rXJQFD3swqh3loRQIo2a+8VhBFbUw6kue//zAq+8G7WsLrKkrZ+9UWH6qDnGXYmHqz3lC7CpWbZYiRuv3rqzabUprUkbKIoHPHm2xr5BaUmDHQna6e8u6AOTOgquyYPYGr+4Sd/fL9CqzysPMCcX7lnbF/rMMR9zUN9ZKeIY3ZDXu7lF+FGc7RerW3fMLI45GxT9ru+26sedMofu126xiihKuAHRxAX2Wl1fTei/6X5ksXsycn60/UAY4t6E1aV66IbVJR6NJL9yYs6JXD76kuuDVDUJhUu6AEned4PW6npauFc71gzU6MRZJm+qedmSI
Base64 Decoded: 1E 64 FD 8C 07 4B 2E DA 04 4F 2E D8 20 DA B0 69 49 E5 A2 C5 60 29 18 B1 37 79 E9 06 C2 73 3C 17 19 96 5A 45 6E 21 27 FE F0 C9 10 CB BB FC D1 37 C5 35 C9 42 3C C1 4E 7E 84 97 DE 8F D3 40 44 1F 0A 48 63 4C CA A6 D6 4E 5D 23 BD 2B C4 F0 6D 39 98 AD C3 10 F7 76 31 D1 74 78 F8 C8 51 68 66 3E 9E CB A5 55 1D 1B AC 0C 06 B2 6E 77 8A 96 E4 29 2D E9 03 68 3E 4F AD EB 5C 94 05 0F 7B 30 AA 1D E5 A1 14 08 A3 66 BE F1 58 41 15 B5 30 EA 4B 9E FF FC C0 AB EF 06 ED 6B 0B AC A9 2B 67 EF 54 58 7E AA 0E 71 97 62 61 EA CF 79 42 EC 2A 56 6D 96 22 46 EB F7 AE AC DA 6D 4A 6B 52 46 CA 22 81 CF 1E 6D B1 AF 90 5A 52 60 C7 42 76 BA 7B CB BA 00 E4 CE 82 AB B2 60 F6 06 AF EE 12 77 F7 CB F4 2A B3 CA C3 CC 09 C5 FB 96 76 C5 FE B3 0C 47 DC D4 37 D6 4A 78 86 37 64 35 EE EE 51 7E 14 67 3B 45 EA D6 DD F3 0B 23 8E 46 C5 3F 6B BB ED BA B1 E7 4C A1 FB B5 DB AC 62 8A 12 AE 00 74 71 01 7D 96 97 57 D3 7A 2F FA 5F 99 2C 5E CC 9C 9F AD 3F 50 06 38 B7 A1 35 69 5E BA 21 B5 49 47 A3 49 2F DC 98 B3 A2 57 0F BE A4 BA E0 D5 0D 42 61 52 EE 80 12 77 9D E0 F5 BA 9E 96 AE 15 CE F5 83 35 3A 31 16 49 9B EA 9E 76 64 7F
Decrypted HEX: 7B 22 72 65 73 75 6C 74 22 3A 22 53 55 43 43 45 53 53 22 2C 22 6D 65 73 73 61 67 65 22 3A 22 28 6E 6F 6E 65 29 22 2C 20 22 61 63 74 69 6F 6E 73 22 3A 5B 7B 22 61 63 74 69 6F 6E 22 3A 22 69 6E 69 74 69 61 74 69 6F 6E 22 2C 22 64 61 74 61 22 3A 5B 7B 22 74 79 70 65 22 3A 22 49 4F 5F 43 4F 4E 54 52 4F 4C 4C 45 52 22 2C 22 69 6E 70 75 74 50 69 6E 73 22 3A 22 22 2C 22 6F 75 74 70 75 74 50 69 6E 73 4D 61 6E 75 61 6C 22 3A 22 22 2C 22 72 65 6C 61 79 44 65 66 61 75 6C 74 53 74 61 74 65 22 3A 22 22 2C 22 69 6E 70 75 74 52 65 73 69 73 74 61 6E 63 65 22 3A 22 22 2C 22 69 6E 70 75 74 50 69 6E 73 4D 61 6E 75 61 6C 22 3A 22 22 2C 42 89 FE 3F 00 00 00 00 0D 0A 00 25 35 78 20 40 42 89 FE 3F D0 00 00 00 20 00 00 00 C7 08 10 40 09 00 00 00 00 00 00 00 F0 A7 C6 4B 0F 00 00 00 54 58 20 40 10 E9 FE 3F 40 89 FE 3F 60 58 20 40 54 58 20 40 10 E9 FE 3F 40 89 FE 3F 21 5B 20 40 C8 FB FF 3F 60 FA FF 3F 10 E9 FE 3F 18 5C 20 40 54 58 20 40 10 E9 FE 3F ED 88 FE 3F 5E 15 20 40 68 01 00 00 10 E9 FE 3F ED 88 FE 3F 21 5B 20 40 10 E9 FE 3F 68 01 00 00 00 00 00 00 B0 FD FF 3F 10 E9 FE 3F 68 01 00 00
Decrypted JSON String: {"result":"SUCCESS","message":"(none)", "actions":[{"action":"initiation","data":[{"type":"IO_CONTROLLER","inputPins":"","outputPinsManual":"","relayDefaultState":"","inputResistance":"","inputPinsManual":"",B⸮⸮?
如果您怀疑自己 运行 内存不足,您可以尝试通过双重用途回收内存缓冲区。例如,重新使用包含 base64 数据 f 的输入缓冲区来存储解码后的 json,这将为您节省至少 208 字节的 RAM。对于您的情况可能就足够了。检验这一理论所需要做的就是:
byte* jsonByte = (byte*)encoded; // save decodedLength bytes of RAM
为了进一步节省,您还可以尝试就地解码 base64,对输入和输出使用单个缓冲区。如果你的 base64 解码不能做到(它很可能可以),那么写你自己的可以,这绝对是可行的,而且痛苦很小。这可以为您再节省 208 个字节,这是相当多的。为了对此进行测试,将 decodedChar 的声明更改为:
char* decodedChar = encoded;
Base64.decodedLength() 总是 return (result.length() * 5) / 8,它总是小于传入的字节数。
另外,解密还有更多的潜在节省。一方面,解密可以完成 in_place.
for (int i = 0; i < (des.get_size() / 8); i++) {
byte intermitInput[8];
byte intermitResult[8]; // not needed
for (int j = 0; j < 8; j++) {
intermitInput[j] = (byte) decodedChar[(i * 8) + j];
}
des.decrypt(intermitResult, intermitInput, key);
for (int j = 0; j < 8; j++) {
jsonByte[(i * 8) + j] = intermitResult[j];
}
}
// could be done in-place with no loss of functionality,
// and a noticeable performance gain. Copying data takes
// time, too.
for (int i = 0; i < des.get_size(); i += 8) {
byte intermitInput[8];
for (int j = 0; j < 8; j++) {
intermitInput[j] = (byte) decodedChar[i + j];
}
des.decrypt((byte*)decodedChar + i, intermitInput, key);
}
// result is in array decodedCher. array jsonBytes is not needed anymore.
这里:
// you use 208 bytes of RAM only to add a null terminating character.
// when you coud have simply allocated 1 more byte in jsonByte[], avoided
// this entire loop, and made your function run faster at the same time.
char json[sizeof(jsonByte) + 1];
for (int i = 0; i < sizeof(jsonByte); i++) {
json[i] = (char)jsonByte[i];
}
json[sizeof(jsonByte)] = '[=13=]';
我估计您可以在此函数中回收至少 600 字节的 RAM,这将允许您处理更大的 jsons。
根据您问题中提供的详细信息,无法估计您能够处理的 json 大小。
此外,由于您的 arduino 在 printArray() 中存在错误,我会检查那里是否有任何不太有用的大型中间数组。在打印函数中,任何大于 16 字节的数组对于手头的任务来说已经太大了。理想情况下,打印函数中根本不应该有中间数组。
回顾一下:您可以而且应该重新组织您的代码以仅使用一个数组作为输入、所有中间结果和最终 json。 RAM 资源在小型微处理器和 Arduinos 上非常有限。使用后,您会发现嵌入式算法和库,如 DES 加密,是专门构建的,因此资源成本尽可能小。
另一个需要探索的领域:json 结果是否由 Arduino 解析?如果没有,整个序列很可能一次完成 8 个字节,读取一个 10 个字节的块,然后将生成的 8 个字节发送到 Pi,为您提供无价的处理能力 json s 的大小不受限制,至少在 arduino 方面是这样。
我正在尝试将 NODE_MCU_V3 添加到我有 运行 Raspberry 和 Java 库的小型 BMS 系统。
设备调用服务器,并得到 JSON 响应。此响应经过 DES 加密,然后进行 Base64 编码。信息的发送与编码配合得很好,而接收响应则适用于较小的响应。但如果 JSON 超过 208 个字符,则解密失败。我对 Arduino 和 C 不太熟悉,但我猜它与尺寸有关。
这是相关代码。结果是从服务器响应中获取的字符串。 Base64 解码器的结果是预期的,问题出在 DES 解码器上。我在 HEX 的底部添加了示例。
char encoded[result.length()];
result.toCharArray(encoded, result.length());
// Convert back.
int decodedLength = Base64.decodedLength(encoded, sizeof(encoded));
char decodedChar[decodedLength];
Base64.decode(decodedChar, encoded, sizeof(encoded));
Serial.print("Decoded: "); printArray((byte*) decodedChar, sizeof(decodedChar));
byte jsonByte[decodedLength];
for (int i = 0; i < (des.get_size() / 8); i++) {
byte intermitInput[8];
byte intermitResult[8];
for (int j = 0; j < 8; j++) {
intermitInput[j] = (byte) decodedChar[(i * 8) + j];
}
des.decrypt(intermitResult, intermitInput, key);
for (int j = 0; j < 8; j++) {
jsonByte[(i * 8) + j] = intermitResult[j];
}
}
Serial.print("Decrypted: "); printArray(jsonByte, sizeof(jsonByte));
char json[sizeof(jsonByte) + 1];
for (int i = 0; i < sizeof(jsonByte); i++) {
json[i] = (char)jsonByte[i];
}
json[sizeof(jsonByte)] = '[=10=]';
Serial.print("Decripted result:\t");
Serial.println(json);
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, json);
// Test if parsing succeeds.
if (error) {
Serial.print(F("deserializeJson() failed."));
return;
}
const char* resultStatus = doc["result"];
if (strstr(resultStatus, "SUCCESS") < 0) {
Serial.print("Problem with the response: "); Serial.println(resultStatus);
return;
}
Serial.print(" Value: "); Serial.println(resultStatus);
服务器:
Json - Datalength: 359 - {"result":"SUCCESS","message":"(none)", "actions":[{"action":"initiation","data":[{"type":"IO_CONTROLLER","inputPins":"","outputPinsManual":"","relayDefaultState":"","inputResistance":"","inputPinsManual":"","outputPins":"4"}], "hostname":"AR-259bfc91250", "macAddress":"null"},{"action":"campAlarm","value":"false"},{"action":"warningBeep","value":"false"}]}
Clear JSON HEX: 7b22726573756c74223a2253554343455353222c226d657373616765223a22286e6f6e6529222c2022616374696f6e73223a5b7b22616374696f6e223a22696e6974696174696f6e222c2264617461223a5b7b2274797065223a22494f5f434f4e54524f4c4c4552222c22696e70757450696e73223a22222c226f757470757450696e734d616e75616c223a22222c2272656c617944656661756c745374617465223a22222c22696e707574526573697374616e6365223a22222c22696e70757450696e734d616e75616c223a22222c226f757470757450696e73223a2234227d5d2c2022686f73746e616d65223a2241522d3235396266633931323530222c20226d616341646472657373223a226e756c6c227d2c7b22616374696f6e223a2263616d70416c61726d222c2276616c7565223a2266616c7365227d2c7b22616374696f6e223a227761726e696e6742656570222c2276616c7565223a2266616c7365227d5d7d
Encrypted before Base64: 1e64fd8c074b2eda044f2ed820dab06949e5a2c5602918b13779e906c2733c1719965a456e2127fef0c910cbbbfcd137c535c9423cc14e7e8497de8fd340441f0a48634ccaa6d64e5d23bd2bc4f06d3998adc310f77631d17478f8c85168663e9ecba5551d1bac0c06b26e778a96e4292de903683e4fadeb5c94050f7b30aa1de5a11408a366bef1584115b530ea4b9efffcc0abef06ed6b0baca92b67ef54587eaa0e71976261eacf7942ec2a566d962246ebf7aeacda6d4a6b5246ca2281cf1e6db1af905a5260c74276ba7bcbba00e4ce82abb260f606afee1277f7cbf42ab3cac3cc09c5fb9676c5feb30c47dcd437d64a7886376435eeee517e14673b45ead6ddf30b238e46c53f6bbbedbab1e74ca1fbb5dbac628a12ae007471017d969757d37a2ffa5f992c5ecc9c9fad3f500638b7a135695eba21b54947a3492fdc98b3a2570fbea4bae0d50d426152ee8012779de0f5ba9e96ae15cef583353a3116499bea9e766488
Base64 send: HmT9jAdLLtoETy7YINqwaUnlosVgKRixN3npBsJzPBcZllpFbiEn/vDJEMu7/NE3xTXJQjzBTn6El96P00BEHwpIY0zKptZOXSO9K8TwbTmYrcMQ93Yx0XR4+MhRaGY+nsulVR0brAwGsm53ipbkKS3pA2g+T63rXJQFD3swqh3loRQIo2a+8VhBFbUw6kue//zAq+8G7WsLrKkrZ+9UWH6qDnGXYmHqz3lC7CpWbZYiRuv3rqzabUprUkbKIoHPHm2xr5BaUmDHQna6e8u6AOTOgquyYPYGr+4Sd/fL9CqzysPMCcX7lnbF/rMMR9zUN9ZKeIY3ZDXu7lF+FGc7RerW3fMLI45GxT9ru+26sedMofu126xiihKuAHRxAX2Wl1fTei/6X5ksXsycn60/UAY4t6E1aV66IbVJR6NJL9yYs6JXD76kuuDVDUJhUu6AEned4PW6npauFc71gzU6MRZJm+qedmSI
Arduino:
Base64 coming in: HmT9jAdLLtoETy7YINqwaUnlosVgKRixN3npBsJzPBcZllpFbiEn/vDJEMu7/NE3xTXJQjzBTn6El96P00BEHwpIY0zKptZOXSO9K8TwbTmYrcMQ93Yx0XR4+MhRaGY+nsulVR0brAwGsm53ipbkKS3pA2g+T63rXJQFD3swqh3loRQIo2a+8VhBFbUw6kue//zAq+8G7WsLrKkrZ+9UWH6qDnGXYmHqz3lC7CpWbZYiRuv3rqzabUprUkbKIoHPHm2xr5BaUmDHQna6e8u6AOTOgquyYPYGr+4Sd/fL9CqzysPMCcX7lnbF/rMMR9zUN9ZKeIY3ZDXu7lF+FGc7RerW3fMLI45GxT9ru+26sedMofu126xiihKuAHRxAX2Wl1fTei/6X5ksXsycn60/UAY4t6E1aV66IbVJR6NJL9yYs6JXD76kuuDVDUJhUu6AEned4PW6npauFc71gzU6MRZJm+qedmSI
Base64 Decoded: 1E 64 FD 8C 07 4B 2E DA 04 4F 2E D8 20 DA B0 69 49 E5 A2 C5 60 29 18 B1 37 79 E9 06 C2 73 3C 17 19 96 5A 45 6E 21 27 FE F0 C9 10 CB BB FC D1 37 C5 35 C9 42 3C C1 4E 7E 84 97 DE 8F D3 40 44 1F 0A 48 63 4C CA A6 D6 4E 5D 23 BD 2B C4 F0 6D 39 98 AD C3 10 F7 76 31 D1 74 78 F8 C8 51 68 66 3E 9E CB A5 55 1D 1B AC 0C 06 B2 6E 77 8A 96 E4 29 2D E9 03 68 3E 4F AD EB 5C 94 05 0F 7B 30 AA 1D E5 A1 14 08 A3 66 BE F1 58 41 15 B5 30 EA 4B 9E FF FC C0 AB EF 06 ED 6B 0B AC A9 2B 67 EF 54 58 7E AA 0E 71 97 62 61 EA CF 79 42 EC 2A 56 6D 96 22 46 EB F7 AE AC DA 6D 4A 6B 52 46 CA 22 81 CF 1E 6D B1 AF 90 5A 52 60 C7 42 76 BA 7B CB BA 00 E4 CE 82 AB B2 60 F6 06 AF EE 12 77 F7 CB F4 2A B3 CA C3 CC 09 C5 FB 96 76 C5 FE B3 0C 47 DC D4 37 D6 4A 78 86 37 64 35 EE EE 51 7E 14 67 3B 45 EA D6 DD F3 0B 23 8E 46 C5 3F 6B BB ED BA B1 E7 4C A1 FB B5 DB AC 62 8A 12 AE 00 74 71 01 7D 96 97 57 D3 7A 2F FA 5F 99 2C 5E CC 9C 9F AD 3F 50 06 38 B7 A1 35 69 5E BA 21 B5 49 47 A3 49 2F DC 98 B3 A2 57 0F BE A4 BA E0 D5 0D 42 61 52 EE 80 12 77 9D E0 F5 BA 9E 96 AE 15 CE F5 83 35 3A 31 16 49 9B EA 9E 76 64 7F
Decrypted HEX: 7B 22 72 65 73 75 6C 74 22 3A 22 53 55 43 43 45 53 53 22 2C 22 6D 65 73 73 61 67 65 22 3A 22 28 6E 6F 6E 65 29 22 2C 20 22 61 63 74 69 6F 6E 73 22 3A 5B 7B 22 61 63 74 69 6F 6E 22 3A 22 69 6E 69 74 69 61 74 69 6F 6E 22 2C 22 64 61 74 61 22 3A 5B 7B 22 74 79 70 65 22 3A 22 49 4F 5F 43 4F 4E 54 52 4F 4C 4C 45 52 22 2C 22 69 6E 70 75 74 50 69 6E 73 22 3A 22 22 2C 22 6F 75 74 70 75 74 50 69 6E 73 4D 61 6E 75 61 6C 22 3A 22 22 2C 22 72 65 6C 61 79 44 65 66 61 75 6C 74 53 74 61 74 65 22 3A 22 22 2C 22 69 6E 70 75 74 52 65 73 69 73 74 61 6E 63 65 22 3A 22 22 2C 22 69 6E 70 75 74 50 69 6E 73 4D 61 6E 75 61 6C 22 3A 22 22 2C 42 89 FE 3F 00 00 00 00 0D 0A 00 25 35 78 20 40 42 89 FE 3F D0 00 00 00 20 00 00 00 C7 08 10 40 09 00 00 00 00 00 00 00 F0 A7 C6 4B 0F 00 00 00 54 58 20 40 10 E9 FE 3F 40 89 FE 3F 60 58 20 40 54 58 20 40 10 E9 FE 3F 40 89 FE 3F 21 5B 20 40 C8 FB FF 3F 60 FA FF 3F 10 E9 FE 3F 18 5C 20 40 54 58 20 40 10 E9 FE 3F ED 88 FE 3F 5E 15 20 40 68 01 00 00 10 E9 FE 3F ED 88 FE 3F 21 5B 20 40 10 E9 FE 3F 68 01 00 00 00 00 00 00 B0 FD FF 3F 10 E9 FE 3F 68 01 00 00
Decrypted JSON String: {"result":"SUCCESS","message":"(none)", "actions":[{"action":"initiation","data":[{"type":"IO_CONTROLLER","inputPins":"","outputPinsManual":"","relayDefaultState":"","inputResistance":"","inputPinsManual":"",B⸮⸮?
如果您怀疑自己 运行 内存不足,您可以尝试通过双重用途回收内存缓冲区。例如,重新使用包含 base64 数据 f 的输入缓冲区来存储解码后的 json,这将为您节省至少 208 字节的 RAM。对于您的情况可能就足够了。检验这一理论所需要做的就是:
byte* jsonByte = (byte*)encoded; // save decodedLength bytes of RAM
为了进一步节省,您还可以尝试就地解码 base64,对输入和输出使用单个缓冲区。如果你的 base64 解码不能做到(它很可能可以),那么写你自己的可以,这绝对是可行的,而且痛苦很小。这可以为您再节省 208 个字节,这是相当多的。为了对此进行测试,将 decodedChar 的声明更改为:
char* decodedChar = encoded;
Base64.decodedLength() 总是 return (result.length() * 5) / 8,它总是小于传入的字节数。
另外,解密还有更多的潜在节省。一方面,解密可以完成 in_place.
for (int i = 0; i < (des.get_size() / 8); i++) {
byte intermitInput[8];
byte intermitResult[8]; // not needed
for (int j = 0; j < 8; j++) {
intermitInput[j] = (byte) decodedChar[(i * 8) + j];
}
des.decrypt(intermitResult, intermitInput, key);
for (int j = 0; j < 8; j++) {
jsonByte[(i * 8) + j] = intermitResult[j];
}
}
// could be done in-place with no loss of functionality,
// and a noticeable performance gain. Copying data takes
// time, too.
for (int i = 0; i < des.get_size(); i += 8) {
byte intermitInput[8];
for (int j = 0; j < 8; j++) {
intermitInput[j] = (byte) decodedChar[i + j];
}
des.decrypt((byte*)decodedChar + i, intermitInput, key);
}
// result is in array decodedCher. array jsonBytes is not needed anymore.
这里:
// you use 208 bytes of RAM only to add a null terminating character.
// when you coud have simply allocated 1 more byte in jsonByte[], avoided
// this entire loop, and made your function run faster at the same time.
char json[sizeof(jsonByte) + 1];
for (int i = 0; i < sizeof(jsonByte); i++) {
json[i] = (char)jsonByte[i];
}
json[sizeof(jsonByte)] = '[=13=]';
我估计您可以在此函数中回收至少 600 字节的 RAM,这将允许您处理更大的 jsons。
根据您问题中提供的详细信息,无法估计您能够处理的 json 大小。
此外,由于您的 arduino 在 printArray() 中存在错误,我会检查那里是否有任何不太有用的大型中间数组。在打印函数中,任何大于 16 字节的数组对于手头的任务来说已经太大了。理想情况下,打印函数中根本不应该有中间数组。
回顾一下:您可以而且应该重新组织您的代码以仅使用一个数组作为输入、所有中间结果和最终 json。 RAM 资源在小型微处理器和 Arduinos 上非常有限。使用后,您会发现嵌入式算法和库,如 DES 加密,是专门构建的,因此资源成本尽可能小。
另一个需要探索的领域:json 结果是否由 Arduino 解析?如果没有,整个序列很可能一次完成 8 个字节,读取一个 10 个字节的块,然后将生成的 8 个字节发送到 Pi,为您提供无价的处理能力 json s 的大小不受限制,至少在 arduino 方面是这样。