Nodejs——使用javascript计算两个32位字的日期

Nodejs - use javascript to calculate the date of two 32-bit words

我正在编写解析 pcapng 文件(A wire shark pcap 下一代文件)的解析器。虽然有解决方案,但我找不到 NPM 生态系统中存在的解决方案。所以我决定自己动手。到目前为止效果很好,我可以成功破译所有不同的块。

目前正在使用 Node 6.11。

虽然我正在努力确定增强数据包块的时间戳。根据文档,这就是 EHP 的组成部分:

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +---------------------------------------------------------------+
 0 |                    Block Type = 0x00000006                    |
   +---------------------------------------------------------------+
 4 |                      Block Total Length                       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 8 |                         Interface ID                          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
12 |                        Timestamp (High)                       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16 |                        Timestamp (Low)                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20 |                    Captured Packet Length                     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
24 |                    Original Packet Length                     |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
28 /                                                               /
   /                          Packet Data                          /
   /              variable length, padded to 32 bits               /
   /                                                               /
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   /                                                               /
   /                      Options (variable)                       /
   /                                                               /
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                      Block Total Length                       |
   +---------------------------------------------------------------+

时间戳(高)和时间戳(低):64位时间戳的高32位和低32位。时间戳是一个 64 位无符号整数,表示自 1970-01-01 00:00:00 UTC 以来经过的时间单位数。时间单位的长度由该数据包引用的接口描述块的 'if_tsresol' 选项(参见图 10)指定。请注意,与 libpcap 文件格式中的时间戳不同,增强型数据包块中的时间戳不会保存为两个 32 位值,表示自 1970-01-01 00:00:00 UTC 以来经过的秒数和微秒数。增强型数据包块中的时间戳保存为两个 32 位字,代表单个 64 位数量的高 32 位和低 32 位。

那么,我该如何计算此处的时间戳?显然,这是由两个 32 位字组成的,以创建一个 64 位数字。但是 javascript 不处理 64 位整数。

我曾尝试使用 node-int64,但没有成功。取得了 infinity.

的结果

这是我正在使用的特定缓冲区片段:

Uint8Array[8]
0:46
1:89
2:5
3:0
4:9
5:12
6:15
7:31

它是十六进制表示...

timeBuffer.toString('hex')
"2e590500090c0f1f"

这个缓冲区实际上是Timestamp(high)的前四个字节,4-8字节就是Timestamp(low)。

基本上我是想在这里确定实际的时间戳。例如,我可以通过将数值传递给 new Date(12345678789) 来实现。只是无法理解这种存储方式。有人如何把两个 32 位的单词粘在一起,这样我就可以抽出自 1970 年以来的时间?

是的,JS 不支持 64 位整数,但是你总是可以使用浮点数。由于舍入误差,微秒部分将不准确,但由于您使用的是标准 js 日期,它只有毫秒分辨率,所以这应该不是问题:

buf = Buffer.from("2e590500090c0f1f", 'hex')

h = buf.readUInt32LE(0);
l = buf.readUInt32LE(4);

t = h * 0x100000000 + l;

console.log(new Date(t / 1000)); // 2017-09-14T22:51:48.000Z

您的其他解决方案不起作用可能是因为格式有点混乱:64 位数字存储为大端(最高部分在前),而其部分(32 位字)为小端。