关于文件:C#中的二进制补丁生成

关于文件:C#中的二进制补丁生成

Binary patch-generation in C#

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

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

实现必须相对较快,并且可以处理大型文件。它应该表现出O(n)或O(logn)运行时。

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

任何建议或实现的指针都将是不错的选择。

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

我制定的最幼稚的算法仅适用于可保留在内存中的文件,如下所示: pb>

  • 从旧文件中获取前四个字节,将其称为键
  • 将这些字节添加到字典中,其中键-> position,其中position是我抓取这四个字节的位置,从0开始以
  • 跳过这四个字节中的第一个,再获取另外4个(3个重叠,1个),并以相同的方式添加到字典中
  • 对所有重复1-3步旧文件中的4个字节块
  • 从新文件的开头抓取4个字节,然后尝试在字典中查找它。
  • 如果找到,则找到最长的匹配项通过比较两个文件中的字节来比较几个
  • 在旧文件中编码对该位置的引用,并跳过新文件中的匹配块
  • 如果找不到,请从新fi le,然后跳过它。
  • 为新文件的其余部分重复步骤5-8。
  • 这有点像压缩,没有窗口,因此它将占用大量内存。但是,只要我尝试使代码输出最小化,它就相当快,并且会产生很小的补丁。

    一种内存效率更高的算法使用窗口化,但是会产生更大的补丁文件。 >

    在本文中,我跳过了上述算法的更多细微差别,但如有必要,我可以发布更多详细信息。但是,我确实确实确实需要一个不同的算法,因此,对上述算法进行改进可能不会使我走得太远。

    编辑#1:以下是上述算法的详细说明。

    首先,将两个文件合并,以使您拥有一个大文件。记住两个文件之间的切入点。

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

    第三,从新位置开始文件开始,尝试查找现有的4个字节的组合并进行循环,并找到最长的匹配项。确保仅考虑旧文件中的位置,或者仅考虑新文件中当前位置以外的位置。这样可以确保我们可以在补丁应用期间重新使用旧文件和新文件中的材料。

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

    您可能会收到有关证书已使用的警告一些问题。我不知道如何解决这个问题,所以暂时只接受证书。

    源使用了我库其余部分的许多其他类型,所以文件并不需要全部,但这就是该算法的实现。

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

    或者我只是很稠密...:)

    我快速浏览了您提供的那个站点中的算法,但是很遗憾可用的。来自二进制diff文件的注释说:

    Finding an optimal set of differences requires quadratic time relative to the input size, so it becomes unusable very quickly.

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

    感谢您的回答,

    编辑#1:注意,我将查看他的代码以查看是否可以找到一些想法,并且稍后还将向他发送电子邮件给他,但是我已经阅读了他所参考的那本书,尽管该解决方案非常适合寻找最佳解决方案,但是由于时间的限制,该解决方案在实际中并不实用。

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


    对不起,我没有更多帮助。我一定会继续关注xdelta,因为我已经多次使用它来对我们为分发产品而生成的600MB ISO文件产生质量差异,并且效果非常好。


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

    原始的实现在C中,但是此处描述了C#端口,并在此处提供。


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


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

    http://msdn.microsoft.com/zh-cn/library/aa370578(VS.85).aspx


    可能值得检查一下其他人在这个领域中正在做什么,也不一定在C#领域中。

    这也是一个用c#

    SVN编写的库有一个二进制的diff算法,我知道在python中有一个实现,尽管我无法通过快速搜索找到它。他们可能会给您一些改进自己算法的想法


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

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


    推荐阅读