有没有人知道或者知道C#中的二进制补丁生成算法实现?

基本上,比较两个文件(指定旧的新的 ),并生成一个补丁文件,可用于升级文件以具有与文件相同的内容。

实现必须相对较快,并使用大文件。 它应该表现出O(n)或O(logn)运行时。

我自己的算法往往是糟糕的(快速但产生巨大的补丁)或缓慢(产生小补丁但具有O(n ^ 2)运行时)。

任何建议或实施指针都会很好。

具体来说,该实现将用于使我们拥有一台主服务器的各种大型数据文件保持服务器同步。 当主服务器数据文件发生更改时,我们还需要更新多个异地服务器。

我所做的最天真的算法,仅适用于可以保存在内存中的文件,如下所示:

  1. 文件中获取前四个字节,将其称为密钥
  2. 将这些字节添加到字典中,其中key - > position ,其中position是我抓住那4个字节的位置,0开始于
  3. 跳过这四个字节中的第一个,抓取另外4个(3个重叠,1个),并以相同的方式添加到字典中
  4. 文件中的所有4字节块重复步骤1-3
  5. 从新文件的开头,抓取4个字节,并尝试在字典中查找它
  6. 如果找到,通过比较两个文件中的字节,找到最长匹配(如果有)
  7. 文件中编码对该位置的引用,并跳过文件中的匹配块
  8. 如果未找到,则从文件中编码1个字节,然后跳过它
  9. 文件的其余部分重复步骤5-8

这有点像压缩,没有窗口,所以它会占用大量内存。 然而,它是相当快的,并且产生非常小的补丁,只要我尝试使代码输出最小。

更节省内存的算法使用窗口,但会产生更大的补丁文件。

我在本文中跳过了上述算法的细微差别,但如果有必要,我可以发布更多详细信息。 但是,我确实觉得我需要一个不同的算法,所以改进上述算法可能不会让我足够远。


编辑#1 :以下是对上述算法的更详细描述。

首先,组合这两个文件,这样你就有了一个大文件。 记住两个文件之间的切点。

其次,这样做可以抓取4个字节并将其位置添加到整个文件中的所有内容的字典步骤中。

第三, 从新文件开始的地方开始,尝试定位4字节的现有组合,并找到最长匹配。 确保我们只考虑旧文件中的位置,或者来自新文件中较早的位置 这确保了我们可以在补丁应用期间重用旧文件和新文件中的材料。


编辑#2上述算法的源代码

您可能会收到有关证书存在问题的警告。 我不知道如何解决这个问题,因此暂时只接受证书。

源使用了我库中其余部分的许多其他类型,因此文件不是全部​​,但这就是算法实现。


@lomaxx,我试图为subversion中使用的算法找到一个很好的文档,叫做xdelta,但除非你已经知道算法是如何工作的,否则我发现的文档无法告诉我需要知道的内容。

或者也许我只是密集...... :)

我快速浏览了你所提供的网站上的算法,遗憾的是它无法使用。 二进制diff文件中的注释说:

找到一组最佳差异需要相对于输入大小的二次时间,因此它很快就会变得无法使用。

我的需求并不是最优的,所以我正在寻找更实用的解决方案。

谢谢你的答案,如果我需要它们,他会为他的工具添加一个书签。

编辑#1 :注意,我会查看他的代码,看看我是否能找到一些想法,我也会稍后给他发一封问题,但我读过他所引用的那本书,虽然解决方案很适合找到最佳解决方案,由于时间要求,它在使用中是不切实际的。

编辑#2 :我肯定会追捕python xdelta实现。

===============>>#1 票数:5 已采纳

对不起,我无法提供更多帮助。 我肯定会继续关注xdelta,因为我已经多次使用它来生成600MB + ISO文件的高质量差异,这些文件是我们为分发我们的产品而生成的,并且表现非常好。

===============>>#2 票数:4

bsdiff旨在为二进制文件创建非常小的补丁。 如其页面所述,它需要max(17*n,9*n+m)+O(1)字节的内存并以O((n+m) log n)时间运行(其中n是旧文件和m是新文件的大小)。

最初的实现是在C中,但这里描述一个C#端口,可在此处获得

===============>>#3 票数:3

你见过VCDiff吗? 它是Misc库的一部分,似乎相当活跃(最新版本r259,2008年4月23日)。 我没有用它,但认为值得一提。

===============>>#4 票数:1

值得一看的是其他一些人在这个领域做了什么,而不一定是在C#领域。

这是一个用c#编写的库

SVN也有一个二进制diff算法,我知道python中有一个实现,虽然我用快速搜索找不到它。 他们可能会给你一些关于在哪里改进自己的算法的想法

===============>>#5 票数:1

如果这是用于安装或分发,您是否考虑过使用Windows Installer SDK? 它具有修补二进制文件的能力。

http://msdn.microsoft.com/en-us/library/aa370578(VS.85).aspx

===============>>#6 票数:0

这是一个粗略的准则,但以下是rsync算法,可用于创建二进制补丁。

http://rsync.samba.org/tech_report/tech_report.html

  ask by Lasse Vågsæther Karlsen translate from so

未解决问题?本站智能推荐:

1回复

优化“补丁”流程

对于某些项目,我需要覆盖文件,但是由于用户同时也可能会使用其他程序来编辑此文件,因此我不会经常在运行时保留流,而是将所有数据保存在字节数组中。 保存程序时,应仅保存其编辑的区域,而不是整个文件。 我(做得很差)编写了一个例程来执行此操作,但是它运行缓慢,而且我不知道如何在此处提高性能。 我
1回复

用Python读取二进制文件并将其写入第三个文件中非零字节的另一个补丁中

在Python-3.x中,这是从另一个字节(非零字节)中修补非零字节的二进制文件(创建第三个输出文件)的最佳方法,当然所有这些都保持原始字节顺序吗? 仅读取源文件和补丁文件并逐字节写入源文件不是问题,但是如何逐字节解析它们: 所有文件都小于50kb,速度不成问题。
2回复

在git中创建一个包含特定文件的补丁

假设我是7个在原始/主存储库之前提交的对象。 我想创建一个补丁,在补丁中包括已更改的特定文件,而不是所有文件。 或等效的排除补丁程序中已更改的特定文件。 我该如何实现?
1回复

为什么补丁找不到这个文件?

我想将一个补丁应用到u-boot源代码,但有些如何,Linux不允许我这样做。 我有的: 那么为什么它在完美的位置找不到文件呢? 这里发生了什么?
1回复

将补丁文件应用于Magento核心文件

我编辑了magento的一些核心代码。 之后,我想将所有编辑过的文件打补丁到Magento目录。 我的问题是:如何使用magento实施php补丁? 或如何使用PHP创建补丁文件。 请帮我。
5回复

在SUPEE 7405补丁之后,Chmod 640用于上传文件

安装SUPEE 7405补丁后,我们发现从管理员上传图像时出现问题。 所有文件权限都设置为CHMOD 640,这使得所有用户都无法访问它们。 有没有涉及重写/lib/Varien/File/Uploader.php文件的解决方案?
1回复

WiX选择性补丁和C#

这是一个假设的问题(等待适当的调查),但我相信它可能会导致问题。 AC#应用程序包含一个exe和一些dll。 Visual Studio / msbuild在每次构建时都会略微不同地构建它们(更新的时间戳/ guids / etc),但每个构建在功能上是相同的。 构建服务器处理每日/发
2回复

允许对C#游戏进行补丁/修改的术语

我需要能够允许对一个非常简单的游戏进行修改/补丁。 本质上,我需要允许一个充满DLL文件的文件夹加载,并使它们的功能覆盖原始应用程序的功能。 我知道钩子系统的基本知识,在该钩子系统中,可以在整个应用程序源代码中放置一行代码,以从外部变量等“引入”代码。 我试图进行搜索,但是由于不确
1回复

如何从C#使用Web API补丁

我需要从C#代码中使用Web API PATCH方法。 我的控制器如下 我只是如下尝试了C#代码以使用我的API PATCH方法。 但是上述消耗方法是错误的。 您能告诉我正确的食用方式吗?
1回复

移动Azure服务C#.NET后端补丁未更新

我已经在C#中创建了一个简单的.NET后端移动Azure服务。 我已经启动并运行了移动服务(当前正在做的就是在一张桌子上使用普通的CRUD)。 我遇到的问题是PATCH / UPDATE无法按照它说的那样进行。 我可以做其他所有尝试的事情,例如SELECT,INSERT,DELETE,但是