在Nodejs中解码相同的base64字符串会产生不同的结果

时间:2016-10-26 20:03:41

标签: javascript node.js node-red lora

我在通过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< = LoRa A. 02ABAA6A4152B8C44100C4804200000709< = LoRa B

所以我认为这里发生的是原始的十六进制字符串 分裂成chars并通过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]))));}

1 个答案:

答案 0 :(得分:1)

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

要发送字节&lt; 025555AD4148E1BE4100A06E421954C5BB&gt;,您需要将数据包初始化为:

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";

作为字节,它将以<30>开头,因为<30>是字符“0”的ASCII编码。然后会来<32>,因为这是ASCII字符'2'的编码。因此,而不是位置<02>处的单个字节data[0],您的消息以两个字节<30 32>开头。你可以看到这发生了什么,对吗?该长缓冲区<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>正是您发送的消息的ASCII表示,“025555AD4148E1BE4100A06E421954C5BB”。这证实了你的base64转换没有任何问题。

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