2つの類似した大型生のバイナリの違い

2つの類似した大型生のバイナリの違い

abc私のローカルコンピュータに4 GBのファイルがあるとしましょう。 SFTP経由でリモートサーバーにアップロードしましたが、数時間かかりました。

ローカルでファイルを少し変更して(最大50 MB、ファイルの連続バイトではない)に保存しますabc2。ソースファイルもabcローカルコンピュータに保存されます。

abc合計のバイナリ差を計算する方法はabc2

アプリケーション:

  • フルファイルを再アップロード(数時間かかることがあります)、リモートpatchサーバーから再作成する代わりに、単一のファイル(最大100 MB)のみをリモートサーバーに送信できます。abc2abc2abcpatch

  • ローカルでは、バックアップに8GBを無駄にするのではなく、abc<4100MBのみ+で保存できます。abc2abcpatch

どうすればいいですか?

PS:テキストの場合は知っていますが、diffここでは生のバイナリ形式、つまりzipファイル、実行可能ファイル、または他の種類のファイルで動作できるものを探しています。

PS2:可能であれば使用したくありませんrsync。変更されていないデータを再送信せずに、効率的な方法で2つのシステム間で変更をコピーできることを知っていますが、ここで両方を行うことができるpatch場合はファイルが必要です。後でファイルをコピーしてください。abcpatch

答え1

resticborgbackup2番目のアプリケーション/問題の場合は、「パッチ」や違いを手動で追跡する代わりに、または同じ重複排除バックアッププログラムを使用してください。このresticバックアッププログラムを使用すると、複数のコンピュータのディレクトリを同じバックアップストアにバックアップできるため、単一のコンピュータとコンピュータ間のファイルの断片間のバックアップデータの重複がなくなります。 (私はこのプログラムのユーザーエクスペリエンスがないborgbackupため、このプログラムについて何も言えません。)

ファイルとの違いを計算して保存するために使用できますabcabc2rsync

abcこれは153 MBのサイズの例ですabc2。ファイルがabc2変更され、ファイルの最初の2.3 MBがいくつかの追加データで上書きされました。

$ ls -lh
total 626208
-rw-r--r--  1 kk  wheel   153M Feb  3 16:55 abc
-rw-r--r--  1 kk  wheel   153M Feb  3 17:02 abc2

変換用のパッチを作成し、名前を次のように指定しabcました。abc2abc-diff

$ rsync --only-write-batch=abc-diff abc2 abc
$ ls -lh
total 631026
-rw-r--r--  1 kk  wheel   153M Feb  3 16:55 abc
-rw-------  1 kk  wheel   2.3M Feb  3 17:03 abc-diff
-rwx------  1 kk  wheel    38B Feb  3 17:03 abc-diff.sh
-rw-r--r--  1 kk  wheel   153M Feb  3 17:02 abc2

生成されたファイルabc-diffは、実際のdiff(「パッチファイル」)とabc-diff.shユーザー用に生成された短いシェルスクリプトです。rsync

$ cat abc-diff.sh
rsync --read-batch=abc-diff ${1:-abc}

スクリプトは与えられたファイルと同じように変更されabcます。abc2abc-diff

$ md5sum abc abc2
be00efe0a7a7d3b793e70e466cbc53c6  abc
3decbde2d3a87f3d954ccee9d60f249b  abc2
$ sh abc-diff.sh
$ md5sum abc abc2
3decbde2d3a87f3d954ccee9d60f249b  abc
3decbde2d3a87f3d954ccee9d60f249b  abc2

これでこのファイルをabc-diff別の場所に転送できますabc。コマンドを使用すると、rsync --read-batch=abc-diff abcファイルにパッチを適用して、その内容をabcdiffが作成されたシステムのファイルと同じように変換できます。abc2

パッチをもう一度適用するのは安全なようです。エラーメッセージがなく、ファイルの内容は変更されません(MD5チェックサムは変更されません)。

明示的な「リバースパッチ」を作成しないと、パッチの適用を簡単にキャンセルできません。


また、2.3MBの修正をデータの他の場所abc2、もう少し(約50MB)、最初に書き込むことをテストしました。結果の「パッチ」サイズは4.6MBです。これは、修正されたビットのみがパッチに保存されることを示します。

答え2

abcとabc2のバイナリ差を計算する方法は?

使用bsdiff/bspatchまたはxdeltaなど。

$ bsdiff older newer patch.bin     # patch.bin is created
[...]
$ bspatch older newer patch.bin    # newer is created

ただし、マニュアルページで次の警告に注意してください。

  • bsdiff使用されるメモリはサイズの17倍に等しくなります。古いファイル、サイズの8倍の絶対最小ワークセットサイズが必要です。古いファイル
  • bspatch使用されるメモリサイズは次のとおりです。古いファイルプラスサイズ新しいファイルしかし、かなりのパフォーマンス損失なしに非常に小さな作業セットを許可することができます。

答え3

diffファイルをテキストとして処理するよう強制してみましたか?

diff -ua abc abc2

説明どおりここ

  • -u統合コンテキストのNUM(デフォルト値3)行出力
  • -aすべてのファイルをテキストとして扱う

これでパッチが提供されます。これの欠点は、「ライン」が非常に長くなり、パッチが膨らむ可能性があることです。

答え4

私のテストに基づいて他の答えに追加:

そしてdiff

非常によく似た2つの256MBファイルを作成し、diffファイルを作成しましょうabcabc2

diff -ua abc abc2 > abc-abc2.diff

abc2それでは、元のファイルからabc回復してみましょうabc-abc2.diff

cp abc abc3
patch abc3 < abc-abc2.diff

または

cp abc abc3
patch abc3 -i abc-abc2.diff

または

patch abc -i abc-abc2.diff -o abc3

Linuxで実行できます。 Windowsでも試しましたが(patch.exeとdiff.exeも動作します)、不明な理由で失敗しました。結果abc3ファイルは256MBではなく1KBにすぎませんでした(後でこの回答をここで更新します)。

そしてrsync

許可された回答で詳しく説明されているように、次のように動作します。

rsync --only-write-batch=abc-abc2-diff abc2 abc

cp abc abc3

rsync --read-batch=abc-abc2-diff abc3 

そしてrdiff

もっとこの回答、これは解決策でもあります。

rdiff signature abc abc-signature
rdiff delta abc-signature abc2 abc-abc2-delta

rdiff patch abc abc-abc2-delta abc3

rdiff.exeを使用してWindowsでもテストしました。ここ効果がある

関連情報