首页 > 解决方案 > JS 从缓冲区中读取字节

问题描述

我可以通过一些String破解来解析缓冲区,但必须有一种更直接的方法来从缓冲区数据到最终值。我一直在尝试使用一些buffer.readInt8readInt16LE等等,但还没有运气。第一个和最后一个值在 2 个字节上;如果我理解这里涉及的词汇。其他二对一。

从下面的例子中,我希望得到温度(228)parseInt(buffer.readUInt16BE(6) | (buffer.readUInt16BE(7) << 8), 16)。但这给出了345314198,轻轻地表明我错过了一些东西。

代码

    // (example data in comments)
    
    const buffer = peripheral.advertisement.serviceData[0].data;
    // a4c1380a701400e4233c0ac5c2

    const lameParsing = {
      // Starts with the address a4:c1:38:0a:70:14, then the values
      temperatureC: parseInt(buffer.toString("hex").slice(12, 16), 16) / 10,
      // 22.8
      humidity: parseInt(buffer.toString("hex").slice(16, 18), 16),
      // 35
      battery: parseInt(buffer.toString("hex").slice(18, 20), 16),
      // 60
      batteryV: parseInt(buffer.toString("hex").slice(20, 24), 16) / 1000
      // 2.757
    };

语境

尝试从文档中描述的自定义固件解码来自小米温度计的蓝牙广告数据

标签: javascriptnode.jsbytebuffer

解决方案


这应该是您正在寻找的:

let Buf = Buffer.from("a4c1380a701400e4233c0ac5c2", "hex");
// Let Buf be the buffer from the Bluetooth thermometer.
// Sample data is used here, which matches in your problem.
let TemperatureC = Buf.readUInt16BE(6) / 10
let Humidity = Buf.readUIntBE(8,1)
let Battery = Buf.readUIntBE(9,1)
let BatteryV = (Buf.readUInt16BE(10)) / 1000
// Just to confirm it works...
console.log(TemperatureC,Humidity,Battery,BatteryV)
// Sample output: 22.8 35 60 2.757 (Correct)

每个字节都1在偏移量上。所以,如果我们读取62 个字节然后7,我们实际上是从温度读取第二个字节。记住要考虑到 16 位是 2 个字节;和 NodeJS 按字节偏移。


推荐阅读