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 位字)为小端。
我正在编写解析 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 位字)为小端。