此 Microsoft 文档中的 byte/bit 顺序是什么?
What is the byte/bit order in this Microsoft document?
这是 Windows.lnk 快捷方式格式的文档:
ShellLinkHeader结构是这样描述的:
这是一个文件:
查看 HeaderSize,字节数为 4c 00 00 00
,它应该表示十进制数 76。这是一个小端整数,这里并不奇怪。
接下来是字节为 01 14 02 00 00 00 00 00 c0 00 00 00
的 LinkCLSID,表示值“00021401-0000-0000-C000-000000000046”。 This answer 似乎解释了为什么字节顺序会发生变化,因为最后 8 个字节是字节数组,而其他字节是小端数字。
我的问题是关于 LinkFlags 部分。
LinkFlags部分是这样描述的:
而我的文件中的字节是9b 00 08 00
,或者二进制:
9 b 0 0 0 8 0 0
1001 1011 0000 0000 0000 1000 0000 0000
^
通过比较不同的文件,我发现^
标记的位是文档中的位6/G(标记为红色)。
如何解读?这些字节的顺序与文档中的顺序相同,但每个字节的位都颠倒了吗?
这里的问题源于以下事实:这些规范中显示的位列表根本不适合其下方的 数字。它的目的是在其下方放置 一个位列表,该列表从最低位到最高位,这与我们读取数字的方式完全相反从左到右。
不过,该列表清楚地显示了从 0 到 31 编号的位,这意味着这确实是一个 32 位值,而不是四个字节。具体来说,这意味着在执行任何其他操作之前,需要将原始读取字节解释为单个 32 位整数。与所有其他值一样,这意味着它需要被读取为小端数字,其字节被反转。
因此您的 9b 00 08 00
变为 0008009b
,或者,在二进制中,0000 0000 0000 1000 0000 0000 1001 1011
。
但是,正如我所说,规格中的列表显示了从最低到最高的位数。所以为了适应他们,反转二进制版本:
0 1 2 3
0123 4567 8901 2345 6789 0123 4567 8901
ABCD EFGH IJKL MNOP QRST UVWX YZ@_ ____
---------------------------------------
1101 1001 0000 0000 0001 0000 0000 0000
^
所以第 6 位,在规范中表示为 'G',是 0。
不过,如果您颠倒规格并按逻辑从最高到最低列出位,那么整个事情就更有意义了:
3 2 1 0
1098 7654 3210 9876 5432 1098 7654 3210
____ _@ZY XWVU TSRQ PONM LKJI HGFE DCBA
---------------------------------------
0000 0000 0000 1000 0000 0000 1001 1011
^
0 0 0 8 0 0 9 b
这使得字母参考看起来不那么直观,但它确实非常适合下面的数字版本。该位与您的发现相符(您的值为“9”的第三位),您还可以清楚地看到最高 5 位未使用。
这是 Windows.lnk 快捷方式格式的文档:
ShellLinkHeader结构是这样描述的:
这是一个文件:
查看 HeaderSize,字节数为 4c 00 00 00
,它应该表示十进制数 76。这是一个小端整数,这里并不奇怪。
接下来是字节为 01 14 02 00 00 00 00 00 c0 00 00 00
的 LinkCLSID,表示值“00021401-0000-0000-C000-000000000046”。 This answer 似乎解释了为什么字节顺序会发生变化,因为最后 8 个字节是字节数组,而其他字节是小端数字。
我的问题是关于 LinkFlags 部分。
LinkFlags部分是这样描述的:
而我的文件中的字节是9b 00 08 00
,或者二进制:
9 b 0 0 0 8 0 0
1001 1011 0000 0000 0000 1000 0000 0000
^
通过比较不同的文件,我发现^
标记的位是文档中的位6/G(标记为红色)。
如何解读?这些字节的顺序与文档中的顺序相同,但每个字节的位都颠倒了吗?
这里的问题源于以下事实:这些规范中显示的位列表根本不适合其下方的 数字。它的目的是在其下方放置 一个位列表,该列表从最低位到最高位,这与我们读取数字的方式完全相反从左到右。
不过,该列表清楚地显示了从 0 到 31 编号的位,这意味着这确实是一个 32 位值,而不是四个字节。具体来说,这意味着在执行任何其他操作之前,需要将原始读取字节解释为单个 32 位整数。与所有其他值一样,这意味着它需要被读取为小端数字,其字节被反转。
因此您的 9b 00 08 00
变为 0008009b
,或者,在二进制中,0000 0000 0000 1000 0000 0000 1001 1011
。
但是,正如我所说,规格中的列表显示了从最低到最高的位数。所以为了适应他们,反转二进制版本:
0 1 2 3
0123 4567 8901 2345 6789 0123 4567 8901
ABCD EFGH IJKL MNOP QRST UVWX YZ@_ ____
---------------------------------------
1101 1001 0000 0000 0001 0000 0000 0000
^
所以第 6 位,在规范中表示为 'G',是 0。
不过,如果您颠倒规格并按逻辑从最高到最低列出位,那么整个事情就更有意义了:
3 2 1 0
1098 7654 3210 9876 5432 1098 7654 3210
____ _@ZY XWVU TSRQ PONM LKJI HGFE DCBA
---------------------------------------
0000 0000 0000 1000 0000 0000 1001 1011
^
0 0 0 8 0 0 9 b
这使得字母参考看起来不那么直观,但它确实非常适合下面的数字版本。该位与您的发现相符(您的值为“9”的第三位),您还可以清楚地看到最高 5 位未使用。