HDiffPatch

义项:二进制差分与补丁工具
HDiffPatch

HDiffPatch是一个用C/C++编写的库和命令行工具,用于在二进制文件或文件夹之间生成补丁并还原新版本,支持跨平台运行、多线程与流式处理,并可通过压缩插件控制补丁体积。它由housisong(网络名sisong)以MIT协议开源,最早于2013年5月31日公开,支持超大的文件并允许在差分与打补丁阶段限制内存占用,也兼容bsdiff4等既有补丁格式。该工具常被用于软件与移动应用的增量更新场景。

目录
  1. 定义
  2. 原理
  3. 发展历程
  4. 应用
  5. 局限
  6. 参见

定义

HDiffPatch是一套在字节层面比较新旧数据、据此生成差异数据,再用差异数据与旧数据重组出新数据的工具集。它包含两个部分,一是生成补丁的差分程序hdiffz,二是还原数据的打补丁程序hpatchz[1]。对使用者而言,输入路径既可以是单个文件,也可以是整个目录,因此它也能完成两个版本文件夹之间的同步式更新[1]。

该库按自身格式序列化补丁,同时也能生成和读取若干已有格式:与bsdiff4、endsley/bsdiff的格式相互兼容,并对open-vcdiff与xdelta3所采用的VCDIFF(RFC 3284)格式提供部分兼容[1]。这种兼容性使已有更新链路的项目可以在不改动下游逻辑的前提下替换差分工具[1]。

原理

差分阶段的思路是先在旧数据的字节序列中定位与新数据相同的片段,再用这些片段和新出现的字节共同描述新版本。HDiffPatch采用后缀数组查找公共片段,相关研究指出其时间与空间复杂度优于bsdiff的实现,并通过多线程加速处理[2]。匹配结果被组织为若干“覆盖线”,每条包含新文件起始位置、旧文件起始位置与长度,工具会对被完全包含的覆盖线做删除、对邻近覆盖线做合并,从而减少重复指令[3]。

补丁由控制信息、差异数据与新增数据构成:控制信息指明从旧数据哪个位置取多少字节,差异数据修正取值,新增数据则直接追加[3]。打补丁时按控制信息逐段拷贝与修补,即可得到与目标完全一致的结果,最后可用校验和确认输出正确[1]。

为控制内存,工具提供两种匹配模式。内存模式把整个文件读入内存,所需内存约为新文件大小与旧文件大小的若干倍之和;流模式按固定块长分块匹配,内存占用随块长变化,适合旧文件极大或设备内存有限的情形。补丁可以直接以压缩状态生成,也可通过插件选择zlib、bzip2、lzma、lzma2、zstd等压缩算法,打补丁时无需先完整解压[1]。

补丁包存在多种组织方式:单压缩流格式只需一块解压缓冲区,并支持边下载边打补丁;窗口格式则允许按窗口分段处理;面向微控制器等极小内存设备的精简格式由专门的打补丁程序读取。

发展历程

作者housisong在2004年前后从事PC网络游戏的客户端自动升级,为压缩下载流量而产生制作差分的需求;他曾试用VPatch,因生成补丁速度较慢,转而基于后缀数组自行实现算法,并在2006年撰文记录。早期版本以Delphi编写,2013年他又用C/C++重写了一份实现,并以MIT协议开源,其中差分部分使用C++,打补丁部分为保证可移植性改用纯C。

随着被比对的文件体积增大,内存模式的开销变得突出,因此后续增加了流式差分模式,以略微增大补丁为代价换取更快速度和可控内存。变更记录显示,v2、v3、v4系列分别引入了压缩补丁包、目录间差分与单压缩流补丁包等格式,后续版本继续加入窗口补丁包、与zsync格式兼容的同步差分、就地打补丁以及libdeflate压缩支持等能力。

版本迭代持续进行,2023年8月发布v4.6.7并支持另一种BSDIFF格式,2024年7月发布v4.7.0,2025年6月至8月间先后发布v4.9.0、v4.10.0与v4.11.1[4]。

应用

最常见的使用场景是软件与固件的增量更新:只需下发新版本的差异部分,在本地与旧版本合并,避免重复传输完整的安装文件[5]。在移动应用更新领域,北京大学的EmNets团队针对200款应用做系统测评,将HDiffPatch与xdelta3、bsdiff、archive-patcher并列作为四种常用差分算法加以分析[6]。

该团队测得,在多数情况下HDiffPatch生成的补丁小于xdelta3与bsdiff,差分耗时短于bsdiff,但差分阶段的内存占用高于xdelta3、低于bsdiff[2]。在按压缩率、差分与还原的时间内存开销等指标评估时,这一结论被归因于它对拷贝指令的进一步合并[2]。

React Native热更新方案react-native-update把HDiff算法用于生成体量很小的更新包,并在Android端通过JNI调用其打补丁接口,同时保留lzma、lzma2等压缩支持[7]。其文档也给出实测对比,在纯文本JS包的三类改动场景中,hdiff补丁均小于bsdiff[8]。

此外,面向微控制器与NB-IoT等资源受限设备的精简打补丁程序,使该方案可以用于物联网终端的OTA升级;命令行程序也提供Windows、Linux、macOS版本,并以Android动态库形式供Java代码调用[1]。

局限

HDiffPatch把输入当作纯字节流,不处理文件写入时间、权限、链接等元数据,需要这些信息时应配合其他工具或在调用方扩展[1]。它也不具备rsync式的实时双向同步语义,同步差分是后来通过独立库与示例程序补充的能力。

压缩后的数据在被差分前若未解压,可得相似度会下降;有研究以解压后再差分的方式提升补丁质量,说明直接对压缩容器做差分会损失部分收益[2]。对Hermes字节码这类含偏移表的格式,通用差分会把局部改动放大为大面积差异,react-native-update为此额外施加可逆变换,并指出传统bsdiff与直接hdiff在该场景下补丁分别约为93.7 KB与89.0 KB,改善幅度有限[8]。

性能上存在取舍:内存模式需要数倍于文件大小的内存,流模式虽能压低内存,却会略微增大补丁;窗口类格式在还原时所需内存与窗口大小、解压缓冲区相关[1]。另有研究指出,HDiffPatch的指令合并目前并非最优,合并策略仍有改进空间,并且差分阶段存在较高的CPU开销[2]。

参见

  • bsdiff —— 另一种以最小补丁为目标的二进制差分算法,HDiffPatch可与其补丁格式互通。

  • VCDIFF —— 定义了copy、add、run三类指令的差分编码标准,HDiffPatch对其提供部分兼容。

  • xdelta3 —— 使用滑动窗口与哈希匹配的差分工具,常与HDiffPatch在同一场景下比较。

  • 增量更新 —— 只传输版本差异内容的更新方式,是HDiffPatch的主要用途。

  • zstd —— HDiffPatch可调用的压缩算法之一,用于减小补丁体积。

  • 后缀数组 —— HDiffPatch在内存模式下查找公共片段所依赖的数据结构。

参考资料

  1. HDiffPatch [引用日期2026-10-29]
  2. HDiffPatch [引用日期2026-10-29]
  3. 嵌入式物联网设备OTA全量、增量升级 [引用日期2026-10-29]
  4. CHANGELOG [引用日期2026-10-29]
  5. google.com 上的网页 [引用日期2026-10-29]
  6. ieee.org 上的网页 [引用日期2026-10-29]
  7. deepwiki.com 上的网页 [引用日期2026-10-29]
  8. react-native-update [引用日期2026-10-29]
词条评价
词条统计

浏览次数:2 次

阅读量:0 次 · 阅读完成量:0 次

最近更新:2026-10-28T18:27:58Z

历史版本

本条目引用的词条
bsdiff VCDIFF xdelta3 增量更新 zstd 后缀数组