1

我一直在阅读 xz 文件格式的描述(http://tukaani.org/xz/xz-file-format.txt)。但是当我尝试使用二进制编辑器查看 xz 文件时,它似乎不遵循描述中定义的结构。我错过了什么?

我在 linux(xz 版本 4.999.9beta)中使用 xz cli 实用程序压缩了描述文件(xz-file-format.txt),这些是我得到的前 32 个字节:

FD 37 7A 58 5A 00 00 04 E6 D6 B4 46 02 00 21 01 16 00 00 00 74 2F E5 A3 E0 A9 28 2A 99 5D 00 05

文件的整体结构应该是:流-流填充-流-等等。在这种情况下,我认为应该只有一个流,因为文件中只有一个压缩文件。流的结构是:流头 - 块 - 块 - ... - 块 - 索引 - 流尾。并且流标头的结构是:标头魔术字节-流标志-CRC码。

我可以从我的文件中找到流标头,但是在前 16 个字节之后,它似乎不再遵循描述。

上面的前六个字节显然是魔术字节。接下来的两个字节是流标志。流标志表明正在使用 CRC64,因此 CRC 代码占用接下来的 8 个字节。第十七个字节(我从一个开始数)应该是第一个块的第一个字节。

块的结构是:块头 - 压缩数据 - 块填充 - 检查。块头的结构应该是:块头大小 - 块标志 - 压缩大小 - 未压缩大小 - 过滤器标志列表 - 头部填充 - CRC。所以第十七字节应该是块头大小(我的文件中的 0x16)。这是可能的,但第十八个字节似乎有点奇怪。它应该是块标志位字段。在我的文件中它是空的 - 所以没有设置标志。甚至没有过滤器的数量,根据描述应该是1-4。

由于块标志的第 6 位和第 7 位也为零,因此文件中不应出现压缩和未压缩的大小,并且下一个字节应该是过滤器标志的列表。列表的结构是:过滤器 ID - 属性大小 - 过滤器属性。第十九个字节应该是过滤器ID。这在我的文件中为空,它不是任何官方定义的过滤器 ID。如果它是一个自定义 ID,它将占用 9 个字节,但据我了解,它不可能是描述第 1.2 节中描述的大小编码,因为根据描述:“除了多字节表示的最后一个字节之外的所有字节设置了最高(第八)位。”,但在我的文件中,第 20 个字节也是空的。

那么有什么我不明白的地方,或者文件没有​​按照描述进行吗?

4

1 回答 1

1

我有点匆忙地问了这个问题,并自己想出了一个解决方案。以防万一有人感兴趣,我回答我自己的问题。

我误解了流标头中流标志的含义。它们不会影响标头中的 CRC 代码(始终为 CRC32),只会影响流本身中的 CRC(正如名称流标志所暗示的那样)。这意味着标头中的 CRC 只有四个字节长,因此字节 13-24 形成了有效的块标头。

在块头中,块标志字段又是一个空字节,我之前认为这是一个问题。根据描述,过滤器的数量应该在 1 到 4 之间。所以我希望十进制值至少为 1。由于过滤器的数量用两位表示,最大十进制值为 3,但可能值的数量(包括零)当然是四个,因此零意味着一个过滤器。

由于块标志的最后两位也是零,因此块头中不存在压缩大小或未压缩大小字段。这意味着字节 15-17 是第一个(也是唯一一个)过滤器的过滤器标志。过滤器 id 0x21 是 LZMA2 过滤器的 id。属性大小 0x01 表示一个字节的大小。字典大小 0x16 表示大小为 4096 KiB。

于 2014-11-25T12:41:04.120 回答