【问题标题】:Node.js data parsing raw bytes with BufferNode.js 数据使用 Buffer 解析原始字节
【发布时间】:2012-05-18 21:26:18
【问题描述】:

我正在尝试使用 Buffer 来解析 29 个字节的以奇怪方式格式化的数据。我一直在使用 slice() 方法来分割这些奇怪边界上的数据。十六进制示例流如下所示(为清楚起见添加了空格)...

01 1d 00 00 01 0a 0a 0b 0b 0c 0c 00 00 04 d2 00 00 00 0e c8 00 00 00 00 00 00 00 cc c4

var raw = '011d0000010a0a0b0b0c0c000004d20000000ec800000000000000ccc4';
buff = new Buffer(raw, 'utf8');
var position = 2;

// message type
var msg_type = buff.slice(position,(position+1)).toString();
position += 1;
console.log('... message type is ' + msg_type);

// event type
var event_type = buff.slice(position,(position+1)).toString();
position += 1;
console.log('... event type is ' + event_type);

// grab more data...

这会产生 msg_type=1 和 event_type=0。它应该分别为 0 和 1。以下所有切片都是错误的。

我显然误解了这里的编码。在 Buffer 实例化期间或在 toString() 提取期间。

如何将此输入流视为一系列十六进制字符串并将它们转换为我可以操作的二进制数据?

谢谢!

【问题讨论】:

  • buff.slice(position, position+1) 是返回一个字符还是两个字符?
  • 该缓冲区上的 toString() 结果是一个字符长。但是 toString() 结果在 - buff.slice(position, position+6);长度为 12 个字符。

标签: javascript parsing node.js


【解决方案1】:

Node 的 Buffer 直接通过 hex 编码支持这一点:

var raw = '011d0000010a0a0b0b0c0c000004d20000000ec800000000000000ccc4';
var buff = new Buffer(raw, 'hex');

【讨论】:

    【解决方案2】:

    我认为答案是您的Buffer 并不代表您认为的对象:

    > var raw = '01 02 03'
    > buff = new Buffer(raw, 'utf8')
    <Buffer 30 31 20 30 32 20 30 33>
    > buff.slice(0,0)
    <Buffer >
    > buff.slice(0,1)
    <Buffer 30>
    > buff.slice(0,2)
    <Buffer 30 31>
    > buff.slice(0,3)
    <Buffer 30 31 20>
    > buff.slice(0,0).toString()
    ''
    > buff.slice(0,1).toString()
    '0'
    > buff.slice(0,2).toString()
    '01'
    > buff.slice(0,3).toString()
    '01 '
    > buff.slice(0,4).toString()
    '01 0'
    > buff.slice(0,5).toString()
    '01 02'
    > buff.slice(0,6).toString()
    '01 02 '
    > buff.slice(0,7).toString()
    '01 02 0'
    > buff.slice(0,8).toString()
    '01 02 03'
    > buff.length
    8
    

    这不是表示一个 3 字节长的缓冲区,而是表示一个 8 字节长的缓冲区。当您切入它时,您将获得字符的各个十六进制值。 (注意空格是20——就像%20在URL中无处不在。)

    但我感觉您的var = '01 1d 00...' 只是尝试用一些二进制数据填充缓冲区,而不是程序中实际发生的事情——使用简化版本的实际情况可能更容易填充缓冲区。也许从文件中读取?

    【讨论】:

    • 你说得对,我的例子并不完全准确。原始数据中没有空格。我将编辑问题以反映这一点。
    • 但是您是否收到了一个带有二进制数据的 ascii 编码的十六进制值的字符串?或者你得到的是实际的二进制数据?
    • 我现在使用的示例是一串 ascii 编码的十六进制值。而且我最初的解决方案正在工作 - 我只是错误地增加了位置变量。不过我很好奇,如果数据是通过 Web 服务接口传递的,那么二进制数据是否也是一种选择?
    • 如果您正在使用流,那么 Buffer objects are available on the data events -- 我只是不知道如何将二进制数据的 ASCII 值十六进制表示转换为 Buffer 对象。跨度>
    猜你喜欢
    • 1970-01-01
    • 2019-03-24
    • 2015-11-19
    • 1970-01-01
    • 1970-01-01
    • 2022-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多