ファイルを 64MB ブロックでハッシュしますか?

ファイルを 64MB ブロックでハッシュしますか?

非常に大きなファイル (200GB) があります。どうやら転送時に正しくコピーされなかったようです。両方の sha1 ハッシュが異なります。ファイルをブロック (1MB や 64MB など) に分割し、各ブロックのハッシュを出力する方法はありますか? その後、比較/修正できますか?

それを実行するための簡単なアプリを書くかもしれません。

答え1

その「クイック アプリ」はすでに存在し、比較的よく使われているのが rsync です。もちろん、rsync はそれ以上のことを行いますが、必要なのは非常にシンプルです。

rsync -cvP --inplace user@source:src-path-to-file dest-path-to-file   # from the destination
rsync -cvP --inplace src-path-to-file user@dest:dest-path-to-file     # from the source

デフォルトでは、ssh (または、非常に古いバージョンでは rsh) を使用して接続し、データを転送します。他の方法も可能です。

私が合格したオプションは次のとおりです:

  • -c— ファイル サイズ/mtime ではなく、チェックサムに基づいてスキップします。デフォルトでは、rsync はサイズと mtime が一致する転送を最適化してスキップします。-cチェックサムの計算を強制します (これは I/O の観点からはコストのかかる操作です)。これはブロック ベースのチェックサムであり (ファイル全体のみを実行するように指示しない限り)、破損したブロックのみが転送されることに注意してください。ブロック サイズは自動的に選択されますが、上書きできます-B(上書きする理由はないと思います)。
  • -v— 詳細、詳細を表示します(どのファイルを処理しているか)
  • -P— 部分的なファイル (途中まで進んだ場合でも作業が破棄されない) と進行状況バーの両方をオンにします。
  • --inplace— 一時ファイルではなく、既存のファイルを更新します (一時ファイルは元のファイルを置き換えます)。200 GB の一時ファイルを持つことがなくなります。部分的なファイルも含まれるため、-P部分的に冗長になります。

ところで、元の転送をどのように行ったかはわかりませんが、sftp/scp だった場合は、何かが間違っています。これらはネットワーク上の破損から完全に保護します。原因を突き止める必要があります。RAM の欠陥は比較的よくある原因です。

答え2

ネットワーク接続を介してファイルを別のマシンに再転送する場合は、rsyncを使用する

どこに違いがあるのか​​を知りたい場合、最も簡単な方法は、同じマシンに 2 つのバージョンをインストールすることです。帯域幅が高すぎるためにこれをしたくない場合は、ファイルのチャンクをチェックする方法があります。

このメソッドは、head -cファイルの位置を中断した場所に残すことに依存し、ループを終了する場所を知るためにサイズを事前に計算します。

n=$(($(wc -c <very_large_file) / (64*1024*1024) + 1))
i=0
while [ $i -gt $n ]; do
    head -c 64m | sha256sum
    i=$((i+1))
done <very_large_file

このメソッドは、head -cファイルの位置を中断した場所に残し、cksum各チャンクのサイズを見つけるために使用します (短いチャンクはファイルの終わりを示します)。

while true; do
    output=$(head -c 64m | cksum)
    size=${output#* }; size=${output%% *}
    if [ $size -eq 0 ]; then break; fi
    echo "$output"
done <very_large_file

このメソッドは、dd各チャンクの目的の開始位置にスキップするために呼び出します。

n=$(($(wc -c <very_large_file) / (64*1024*1024) + 1))
i=0
while [ $i -gt $n ]; do
    dd if=very_large_file ibs=64m skip=$i count=1 | sha256sum
    i=$((i+1))
done <very_large_file

答え3

おそらく以下をご覧くださいsplit:

以下に例を記載したマニュアルページを示します。

詳しくはこちら

関連情報