RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1157273
Accepted
andreymal
andreymal
Asked:2020-07-26 01:36:29 +0000 UTC2020-07-26 01:36:29 +0000 UTC 2020-07-26 01:36:29 +0000 UTC

如何从 7z 存档中手动读取元数据?

  • 772

我的任务是手动读取 7z 档案,而不使用 7z 实用程序。它们似乎是使用默认设置创建的,因此很可能版本 4 档案中的数据是使用 LZMA2 算法压缩的(在版本 3 档案中,显然是使用 LZMA1 算法),并且元数据在 LZMA1 中压缩(根据文档)。

使用科学戳方法,我设法从一些(但由于某种原因不是全部)档案中读取数据:

import lzma
with open('archive.7z', 'rb') as fp:
    fp.seek(32)  # Пропускаем 7z-заголовок
    data = lzma.LZMAFile(fp, format=lzma.FORMAT_RAW, filters=[{"id": lzma.FILTER_LZMA2}]).read()

但是,我不知道如何读取元数据。(是否应用了任何特殊过滤器?)

你能告诉我它们是如何编码的以及需要为 lzma 解压缩器设置哪些参数才能读取元数据吗?

7z
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    andreymal
    2022-04-04T22:04:51Z2022-04-04T22:04:51Z

    偶然发现了来自py7zr项目的非官方格式规范。它有点难以阅读,似乎有一些错误,但是这个规范,通过阅读py7zr 源代码,帮助我获得了元数据。

    我不会将规范的一半复制粘贴到这个答案中,但我会注意到一些重要的,在我看来,要点:

    • 该格式有一个特殊的类型 NUMBER - 这是一个可变长度的数字,其中数字的长度由第一个字节中的高位设置,并且必须记住所有 NUMBER 才能正确解码;

    • 如果 End Header 以字节 0x17 开头,则元数据被编码(压缩或加密)并且 End Header 包含解密指令。如果以 0x01 开头,那么元数据直接写入 End Header 而不编码,但是这样的存档非常少见(我的收藏中只找到了一个);

    • 格式中有文件夹、流、编码器和过滤器的复杂概念,它们也会影响元数据的编码并使 End Header 的解析复杂化。但是,显然,一个文件夹、一个流和一个 LZMA1 编码器总是用于没有特殊过滤器的元数据(但这并不准确);

    一般来说,EncodedHeader 结构从 0x17 开始,并包含另外两个结构: PackInfo (0x06) - 有关编码数据的位置和大小的信息;和 UnpackInfo (0x07) - 有关设置编码器和过滤器的信息,以及解码数据的大小及其 CRC32 哈希值。

    从 EncodedHeader 中读取所有这些信息后,我们可以减去压缩的元数据并成功解压:

    # Параметры, прочитанные из структуры EncodedHeader
    pack_position = 0x1d
    pack_size = 0x71
    coder1_properties = b"\x5d\x00\x10\x00\x00"
    unpack_size = 1202
    
    with open("archive.7z", "rb") as fp:
        # Пропускаем заголовок и переходим к сжатым метаданным
        fp.seek(0x20 + pack_position)
        # Читаем сжатые метаданные
        meta_compressed = fp.read(pack_size)
        # Готовим декодер
        decompressor = lzma.LZMADecompressor(
            format=lzma.FORMAT_RAW,
            filters=[lzma._decode_filter_properties(lzma.FILTER_LZMA1, coder1_properties)],
        )
        # Декодируем
        meta = decompressor.decompress(meta_compressed)
        # Декодер может выдать лишние байты, поэтому обязательно обрезаем под нужный размер
        meta = meta[:unpack_size]
    

    将来,这些解压后的元数据也需要进行解析,以便与档案一起进行全面的工作,但这是一个完全不同的故事。

    在我在问题图片中显示的示例存档中,End Header 的排列方式如下(点击放大):

    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5