我正在尝试学习每种类型的 NTFS 记录的原始二进制格式,并且取得了很大的进步。 相关问题
我找到了 Active Disk Editor,它告诉我有关 NTFS 主文件表文件记录等偏移量和字段名称的所有信息,但有一件事我不明白。
在属性 0x10 $STANDARD_INFORMATION 中,时间戳是如何编码的?
比如这个8字节序列:
b'\xb0\x37\x86\x69\x36\x1e\xd7\x01'
,为什么它代表2021-03-21 09:41?
它是如何编码的?
我知道 NTFS 记录中的大多数数字都是小尾数。然而,尝试将其直接转换为整数当然会产生一个非常高的数字,如果使用大端字节顺序,该数字甚至更高:
In [133]: int.from_bytes(b'\xb0\x37\x86\x69\x36\x1e\xd7\x01', 'little')
Out[133]: 132607933078190000
In [134]: int.from_bytes(b'\xb0\x37\x86\x69\x36\x1e\xd7\x01', 'big')
Out[134]: 12697765460832081665
尝试使用这些数字作为
datetime.fromtimestamp
参数将会引发 OSError
:
In [135]: from datetime import datetime
In [136]: datetime.fromtimestamp(132607933078190000)
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
Cell In[136], line 1
----> 1 datetime.fromtimestamp(132607933078190000)
OSError: [Errno 22] Invalid argument
使用前 10 位数字会给出太早的日期:
In [137]: datetime.fromtimestamp(int('132607933078190000'[:11]))
Out[137]: datetime.datetime(2390, 3, 21, 17, 41, 47)
In [138]: datetime.fromtimestamp(int('12697765460832081665'[:11]))
Out[138]: datetime.datetime(2372, 5, 18, 5, 4, 20)
In [139]: datetime.fromtimestamp(int('12697765460832081665'[:10]))
Out[139]: datetime.datetime(2010, 3, 28, 19, 42, 26)
In [140]: datetime.fromtimestamp(int('132607933078190000'[:10]))
Out[140]: datetime.datetime(2012, 1, 9, 11, 22, 10)
那么这个时间戳是如何编码的呢?
NTFS(新技术文件系统)时间戳是一个 64 位值,表示自 1601 年 1 月 1 日(UTC)以来 100 纳秒间隔的数量。时间戳通常用于记录 NTFS 文件系统中的文件创建时间、上次修改时间和上次访问时间。
64位时间戳被分成两个32位DWORD(双字)进行存储和操作。高 32 位表示自 1601 年 1 月 1 日以来经过的整秒数,低 32 位表示 100 纳秒间隔中的秒数。
以下是 64 位时间戳的结构:
高位DWORD(32位):
低 DWORD(32 位):
要将此时间戳转换为人类可读的日期和时间,可以使用标准算法和库来处理转换。许多编程语言和文件系统实用程序提供函数或方法来以更用户友好的格式解释和显示 NTFS 时间戳。