【问题标题】:Decoding same base64 string in Nodejs produces different outcomes在 Nodejs 中解码相同的 base64 字符串会产生不同的结果
【发布时间】:2016-10-26 20:03:40
【问题描述】:

我在通过 LoRa 设备 A 发送数据时遇到了一个小问题。我正在发送一个 十六进制字符串,定义为 String 或 char 字符串(我只发送其中一个,但到目前为止结果相同)

String packet = "025555AD4148E1BE4100A06E421954C5BB";
//char data[] = "025555AD4148E1BE4100A06E421954C5BB";

然而,当我在后端收到它时,字符串在 base64 中看起来像这样。

msg.payload = MDJhYmFhNmE0MTUyYjhjNDQxMDBjNDgwNDIwMDAwMDcwOQ==

这实际上与接收到不同设备 (LoRa B) 的 base64 字符串不同,即使发送的有效负载相同,第二个设备 (LoRa B 设备) 也会收到此msg.payload = AquqakFSuMRBAMSAQgAABwk=

如果我在 nodejs 中使用相同的功能解码 LoRA 和 LoRa B base64

var b = new Buffer(msg.payload,'base64')

我得到以下一堆不是我的十六进制字符串的字符

30326162616136613431353262386334343130306334383034323030303030373039 02ABAA6A4152B8C44100C4804200000709

所以我认为这里发生的是原始的十六进制字符串是 被分成字符并通过 Lora 发送。因此我得到的是 十六进制的 ascii 表示,对吗?

下一个问题是,我怎样才能得到我原来的十六进制字符串?

提前致谢

问候!

编辑:

正如我有根据的猜测所暗示的那样,问题似乎在于有效载荷在发送之前的处理方式,而不是在 base64 编码/解码中

payload = 'MDJhYmFhNmE0MTUyYjhjNDQxMDBjNDgwNDIwMDAwMDcwOQ==';

b = new Buffer(payload,'base64')
console.log("Buffer b raw ");
console.log(b);
console.log("Buffer b stringfied ");
console.log(b.toString());

返回

Buffer b raw 
<Buffer 30 32 61 62 61 61 36 61 34 31 35 32 62 38 63 34 34 31 30 30 63 34 38 30 34 32 30 30 30 30 30 37 30 39>
Buffer b stringfied 
02abaa6a4152b8c44100c4804200000709

查看设备中code that is being used to transmit中的macTransmit函数,可以看出他们正在将packet转换为HEX字符

for (int i = 0; i < size; ++i) {
    this->loraStream->print(static_cast<char>(NIBBLE_TO_HEX_CHAR(HIGH_NIBBLE(payload[i]))));
    this->loraStream->print(static_cast<char>(NIBBLE_TO_HEX_CHAR(LOW_NIBBLE(payload[i]))));}

【问题讨论】:

  • 那么如何将025555AD4148E1BE4100A06E421954C5BB 转换为base64?
  • 这是由 LoRaWAN 堆栈本身完成的,我无法控制,我只需向我的设备提供一个 HEX 字符串。我看到的是 LoRa A 的解码数据是 LoRa B 中数据的 ascii 表示
  • 查看它的文档,了解它如何编码数据和/或它预期的输入格式。
  • base 64 的编码/解码已正确完成,我已经在其他设备上对其进行了测试并且它正在工作,但是这个新设备显示在后端数据似乎以 ascii 表示,而不是十六进制
  • “base 64 的编码/解码已正确完成”,“我得到以下一堆不是我的十六进制字符串的字符”——这两种说法都不可能是真的。但是,如果您想继续猜测而不是阅读文档-玩得开心;-)

标签: javascript node.js node-red lora


【解决方案1】:

您的 LoRa 客户端库希望您给它一个要发送的字节数组,而不是十六进制数字字符串。

要发送字节 ,您需要将数据包初始化为:

char packet[] = {0x02, 0x55, 0x55, 0xAD, 0x41, 0x48, 0xE1, 0xBE, 0x41, 0x00, 0xA0, 0x6E, 0x42, 0x19, 0x54, 0xC5, 0xBB};

当您像在 OP 中那样发送字符串时,这也是一个字节数组。但是每个字节都是一个单个十六进制数字的ASCII编码(两个十六进制数字组成一个字节)。

如果你看一下这串 ASCII 字符

char data[] = "025555AD4148E1BE4100A06E421954C5BB";

作为字节,它将以&lt;30&gt; 开头,因为&lt;30&gt; 是字符“0”的ASCII 编码。然后会出现&lt;32&gt;,因为那是 ASCII 字符“2”的编码。因此,您的消息不是以data[0] 位置的单个字节&lt;02&gt; 开头,而是以两个字节&lt;30 32&gt; 开头。你可以看到这是怎么回事,对吧?那个长缓冲区&lt;Buffer 30 32 61 62 61 61 36 61 34 31 35 32 62 38 63 34 34 31 30 30 63 34 38 30 34 32 30 30 30 30 30 37 30 39&gt; 正是您发送的消息“025555AD4148E1BE4100A06E421954C5BB”的 ASCII 表示。这确认您的 base64 转换没有问题。

您显示的for 循环确认库需要字节。它获取数据包的每个字节,将其分成两个半字节,并将每个半字节(十六进制数字)转换为相应的 ASCII 字符(0-F)。它将数据包作为文本字符发送,因为 Microchip RN2483 LoRa 模块旨在通过串行式协议与其主机控制器进行通信。在内部,它在传输之前将数据包的文本版本转换回字节。

【讨论】:

    猜你喜欢
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多