Deflate压缩块的结构

2024-01-08

我在理解 Deflate 算法时遇到困难(RFC 1951 https://www.rfc-editor.org/rfc/rfc1951).

TL; DR如何解析Deflate压缩块4be4 0200?

我创建了一个包含字母和换行符的文件a\n在里面,然后运行gzip a.txt。结果文件a.txt.gz:

1f8b 0808 fe8b eb55 0003 612e 7478 7400

4be4 0200

07a1 eadd 0200 0000

我知道第一行是带有附加信息的标题,最后一行是 CRC32 加上输入的大小(RFC 1951 https://www.ietf.org/rfc/rfc1951.txt)。这两个不给我带来麻烦。

但是我如何解释压缩块本身(中间线)?

这是它的十六进制和二进制表示:

4be4 0200

0100 1011
1110 0100
0000 0010
0000 0000

据我了解,不知何故这些:

每个压缩数据块以 3 个标头位开始,其中包含以下数据:

  • 第一位 BFINAL
  • 接下来的 2 位 BTYPE

...实际上最终到达了end第一个字节:0100 1011。 (我将跳过这个问题,为什么有人将实际上位于其他内容尾部的东西称为“标题”。)

据我所知,RFC 包含一些内容应该是对此的解释:

  • 数据元素按以下顺序打包成字节 增加字节内的位数,即开始 与字节的最低有效位。
  • 霍夫曼码以外的数据元素被打包 从数据的最低有效位开始 元素。
  • 霍夫曼代码从最重要的开始打包 代码的重要位。

换句话说,如果将压缩数据打印为 字节序列,从第一个字节开始right边际并继续left,与最 像往常一样,左侧每个字节的有效位是 能够从右到左解析结果,宽度固定 元素以正确的 MSB 到 LSB 顺序和霍夫曼代码 位反转顺序(即,代码的第一位 相对 LSB 位置)。

但遗憾的是我不明白这个解释。

回到我的数据。 OK,那么BFINAL就设置好了,那么BTYPE又是什么呢? 10还是01?

如何解释该压缩块中的其余数据?


首先让我们看看压缩数据的十六进制表示形式为一系列字节(而不是您问题中的一系列 16 位大端值):

4b e4 02 00

现在让我们将十六进制字节转换为二进制:

01001011 11100100 00000010 000000000

根据 RFC,这些位是“从字节的最低有效位开始”打包的。字节的最低有效位是该字节的最右边的位。所以第一个字节的第一位是这样的:

01001011 11100100 00000010 000000000
       ^
       first bit

第二位是这个:

01001011 11100100 00000010 000000000
      ^
      second bit

第三位:

01001011 11100100 00000010 000000000
     ^
     third bit

等等。一旦您检查了第一个字节中的所有位,您就可以从第二个字节的最低有效位开始。所以第九位是这样的:

01001011 11100100 00000010 000000000
                ^
                ninth bit

最后一点,即三十秒的一点,是这样的:

01001011 11100100 00000010 000000000
                           ^
                           last bit

BFINAL 值是压缩数据中的第一位,因此包含在上面标记为“第一位”的单个位中。它的值为 1,表示这是压缩数据中的最后一个块。

BTYPE 值存储在数据的接下来两位中。这些是上面标记为“第二位”和“第三位”的位。唯一的问题是两者中哪一位是最低有效位,哪一位是最高有效位。根据 RFC,“霍夫曼代码以外的数据元素被打包 从数据元素的最低有效位开始。”这意味着这两个位中的第一个,即标记为“第二位”的位,是最低有效位。这意味着 BTYPE 的值为01以二进制形式。因此表明该块是使用固定霍夫曼码压缩的。

这是最容易完成的部分。解码压缩块的其余部分更加困难(并且对于更现实的示例,更加困难)。正确解释如何做到这一点将使这个答案对于本网站来说太长(并且您的问题太宽泛)。不过,我会给你一个提示,数据中接下来的三个元素是霍夫曼代码 10010001('a')、00111010('\n')和 0000000(流结束)。其余 6 位未使用,并且不是压缩数据的一部分。

请注意,要了解如何解码 deflate 压缩数据,您必须了解什么霍夫曼码 https://en.wikipedia.org/wiki/Huffman_coding是。您正在遵循的 RFC 假设您这样做。你还应该知道如何LZ77压缩 https://en.wikipedia.org/wiki/LZ77_and_LZ78#LZ77有效,尽管该文档或多或少解释了您需要了解的内容。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Deflate压缩块的结构 的相关文章

  • 使用 NEON 优化 Cortex-A8 颜色转换

    我目前正在执行颜色转换例程 以便从 YUY2 转换为 NV12 我有一个相当快的函数 但没有我预期的那么快 主要是由于缓存未命中 void convert hd uint8 t orig uint8 t result uint32 t wi
  • 如何在gcc中打印UINT64_t?

    为什么这段代码不起作用 include
  • 将位图旋转 90 度

    我有一个1 个 64 位整数 我需要在 8 x 8 区域中旋转 90 度 最好使用直接位操作 我想不出任何方便的算法 例如 这个 0xD000000000000000 110100000000000000000000000000000000
  • 如何将 x86 GCC 风格的 C 内联汇编转换为 Rust 内联汇编?

    我在 C 中有以下内联汇编 unsigned long long result asm volatile byte 15 byte 49 shlq 32 rdx orq rdx rax a result rdx return result
  • MikeOS 引导加载程序中的堆栈段

    我不明白这段代码 mov ax 07C0h Set up 4K of stack space above buffer add ax 544 8k buffer 512 paragraphs 32 paragraphs loader cli
  • 在C语言中如何清屏? [复制]

    这个问题在这里已经有答案了 我想清除屏幕上的所有文字 我尝试过使用 include
  • 这个反斜杠在这段汇编代码中起什么作用?

    我不确定这些推线有什么区别 修剪下来来自 Linux 的 x86 entry calling h https github com torvalds linux blob 241e39004581475b2802cd63c111fec43b
  • 为什么 Linux 对目录使用 getdents() 而不是 read()?

    我浏览 K R C 时注意到 为了读取目录中的条目 他们使用了 while read dp gt fd char dirbuf sizeof dirbuf sizeof dirbuf code Where dirbuf是系统特定的目录结构
  • 这种没有推送寄存器的交换有多安全?

    我对汇编非常陌生 下面的代码应该通过两个不同的函数交换两个整数 首先使用swap c然后使用swap asm 但我怀疑 我是否需要push 我的意思是保存 汇编代码之前寄存器的每个值和pop稍后 就在返回之前 main 换句话说 如果我返回
  • 仅当重复行与模式匹配时才删除它们

    这个问题 https stackoverflow com questions 1444406 how can i delete duplicate lines in a file in unix有一个很好的答案说你可以使用awk seen
  • 如何使用 UNIX shell 计算字母在文本文件中出现的次数?

    我有几个文本文件 我想计算每个字母在每个文件中出现的次数 具体来说 我想使用 UNIX shell 来执行此操作 形式为 cat file 做东西 有没有办法让 wc 命令来执行此操作 grep char o filename wc l
  • 是否可以在Linux上将C转换为asm而不链接libc?

    测试平台为Linux 32位 但也欢迎 Windows 32 位上的某些解决方案 这是一个c代码片段 int a 0 printf d n a 如果我使用 gcc 生成汇编代码 gcc S test c 然后我会得到 movl 0 28 e
  • 如何使用 Bochs 运行汇编代码?

    我想使用 Bochs 作为 8086 模拟器 是否有捷径可寻 我想要的是类似 emu8086 的东西 http www emu8086 com http www emu8086 com 如果程序的初始部分适合 512 字节 并且您不介意将自
  • LC3 LEA指令和存储的值

    我对这个问题感到困惑 指令后寄存器0中存储的值是多少 LEA R0 A 被处决了吗 为什么答案是x370C 我认为应该将A的地址加载到R0中 如果是这样我们怎么知道地址 有人可以帮忙吗 非常感谢 ORIG X3700 LEA R0 A LD
  • 除法和乘法 2 的幂

    我在一篇论文中读到 数字除以 2 的幂并乘以 2 的幂是一个微不足道的过程 我在互联网上搜索了很多解释 但没有得到它 任何人都可以用简单的语言解释一下这实际上意味着什么 从位操作的角度来看 这是微不足道的 乘以2相当于左移1位 除法相当于右
  • 添加冗余赋值可以在未经优化的情况下编译时加快代码速度

    我发现一个有趣的现象 include
  • 如何在 shell 脚本中操作 $PATH 元素?

    有没有一种惯用的方法从类似 PATH 的 shell 变量中删除元素 这就是我想要的 PATH home joe bin usr local bin usr bin bin path to app bin and remove or rep
  • 添加要在给定命令中运行的 .env 变量

    我有一个 env 文件 其中包含如下变量 HELLO world SOMETHING nothing 前几天我发现了这个很棒的脚本 它将这些变量放入当前会话中 所以当我运行这样的东西时 cat env grep v xargs node t
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我
  • 两种情况或 if 哪个更快? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我必须制作一个 非常 轻的脚本 它将接受用户的选项并调用脚本中的函数来执行一些任务 现在我可以使用 IF 和 CASE 选项 但我想知道两

随机推荐

  • 将初始音量设置为手机铃声音量

    我试图做到这一点 以便当用户打开应用程序时 它将音乐的音量设置为手机铃声的音量 到目前为止 这是我的代码 但我不太确定 setVolume float float 上的参数是什么 android 文档没有很好地解释它 我的代码在这里做错了什
  • texture2D().r 和texture2D().a 是什么意思?

    我在用OpenGL ES在Android编程中 当我在着色器中将YUV NV21 转换为RGB时 例如 vec3 yuv vec3 texture2D u TextureY vTextureCoord r 0 0625 texture2D
  • 我们如何使用 ucrop 库自定义裁剪图像活动

    我正在使用一个 implementation com github yalantis ucrop 2 2 2 用于裁剪目的的库 谁能告诉我们如何编辑上面的设计 我们可以为此进行定制设计 UI 吗 因为上面的UI是从图库中选择图片时默认的 l
  • IE11 编辑值时将光标移动到输入开头

    我在一个项目上遇到了一个非常奇怪的问题 长话短说 我有记录利率的输入字段 因此在模糊时附加 并在焦点时删除 它在除 IE11 之外的所有浏览器上都能正常工作 由于某种原因 它将光标移动到输入的开头 这对于人们快速浏览并输入值来说很烦人 这是
  • Nodejs 中哈希字符串的网络安全编码

    我正在 Nodejs 中创建一个重定向器 我有一些价值观 比如 用户id 超级用户id 我想对这些进行哈希处理 以防止用户检索 url 并伪造其他人的 url 并进行 base64 编码以最小化创建的 url 的长度 http myurl
  • Soundcloud API 未通过 Python 返回播放列表中的所有曲目

    我最近开始使用 Soundcloud API 开发一个简单的应用程序 用于保存播放列表中的数据 然而 在我看来 并非播放列表中的所有曲目都会被返回 我正在使用以下代码 import soundcloud shelve time client
  • 如何获取折线图中的所有json值

    我有很多 Json 值 我将使用它们创建一个折线图 但它在图表中只显示一个值 我是 javascript 的新手 有一个想法在图表中绘制所有值 请任何人给出这个问题的 jsfiddle 示例 HTML代码 div class chart S
  • 如何从两个数组列表中删除公共值

    我们如何从两个 ArrayList 中删除公共值 假设我有两个 Arraylist 如下所示 ArrayList1 1 2 3 4 ArrayList1 2 3 4 6 7 我希望得到的结果是 ArrayListFinal 1 6 7 我该
  • 运行 Rails 代码/初始化程序但不通过 Rake

    我的应用程序不断遇到重复出现的问题 基本上 我有一些代码希望它在第一次启动服务器时运行 以检查某些内容是否已定义 例如计划 数据库中的特定列 文件的存在等 然后采取相应的行动 但是 我绝对不希望在启动 Rake 任务 或执行 生成 等操作
  • backgroundTaskHost.exe 退出并显示代码 1 (0x1)

    我正在创建一个 Windows 应用商店应用程序 该应用程序具有用于后台任务的 Windows 运行时组件 该解决方案在 Visual Studio 中构建时没有任何问题 但当触发后台任务时 它总是失败并显示消息 程序 4204 backg
  • 如何使用 Dapper.Contrib 正确“单一化”表名?

    我有一个 Net Core 3 1 控制台应用程序 在SQL Server数据库中 我有单数名称的表 与我的POCO类相同 这方便匹配和维护 对于我想使用的插入 更新和删除操作Dapper Contrib图书馆 但是 当我运行 Insert
  • Qsort 在 C++ 中不适用于哪些类型?

    std sort通过使用交换元素std swap 它又使用复制构造函数和赋值运算符 保证您在交换值时获得正确的语义 qsort通过简单地交换元素的底层位来交换元素 忽略与要交换的类型相关的任何语义 虽然qsort尽管不了解您正在排序的类型的
  • 将变换应用于 UITextView - 防止内容调整大小

    当我将旋转变换应用于UITextView然后点击里面开始编辑 看起来内容尺寸自动变宽了 内容视图的新宽度是旋转视图的边界框的宽度 例如 给定一个宽度为 500 高度为 400 的文本框 并旋转 30 度 新的内容宽度将为 500 cos 3
  • Cassandra 大量 SSTable

    启动一些长时间运行的写入作业 使用 Spark Cassandra 连接器从 Apache Spark 作业批量插入 后 Cassandra v 2 1 为目标表创建了数千个 SSTable 超过 4500 个 次要压缩阈值设置为默认值 4
  • Spark SQL - 如何将 DataFrame 写入文本文件?

    我在用Spark SQL用于读取镶木地板和写入镶木地板文件 但有些情况下 我需要写DataFrame作为文本文件而不是 Json 或 Parquet 是否有任何支持的默认方法或者我必须将该 DataFrame 转换为RDD然后使用saveA
  • Windows 版 Git:致命:早期 EOF

    昨天我安装了一个新的 Git windows 服务器 2 6 4 它与 Mac git 客户端 git 协议 运行良好 今天我正在努力让第二个客户端 Windows 7 正常工作 在尝试使其工作的过程中 我已将 Windows 服务器和客户
  • 本地主机上的 Azure Functions 代理 404

    我有一个 Azure Function App 其 URL 处有一个函数http localhost 7072 api create room以及其他功能 这个特殊的函数是一个HTTPTrigger允许匿名访问并接受GET verb Htt
  • 从 LINQpad 迁移到正确的 Visual Studio 项目?

    我正在 LINQpad 中学习 LINQ to SQL 这很棒 但是背后发生了很多我不太理解的魔法 我正在使用可选的 IQ 驱动程序连接到 Oracle 数据库 该驱动程序可以在 LINQpad 内部下载 我的查询正在运行 现在我需要将其移
  • 发布实现接口的 F# 类时的反射/C# 键入错误

    我有一个用 C 编写的接口 但在用 F 实现它时 我注意到一些奇怪的地方 F 类必须先转换为接口 然后 C 才能使用它 转换后 WPF 无法读取其属性 绑定失败且 SNOOP 无法反映它 我可以用 C 代码包装该对象 一切正常 界面 pub
  • Deflate压缩块的结构

    我在理解 Deflate 算法时遇到困难 RFC 1951 https www rfc editor org rfc rfc1951 TL DR如何解析Deflate压缩块4be4 0200 我创建了一个包含字母和换行符的文件a n在里面