web-dev-qa-db-ja.com

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

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

私はそれを行うための簡単なアプリを書くかもしれません。

1
user4069

その「クイックアプリ」はすでに存在し、比較的一般的です: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 —一時ファイルではなく、既存のファイルを更新します(一時ファイルは元のファイルを置き換えます)。 200GBの一時ファイルを用意する必要がありません。また、部分的なファイルを意味するため、-Pは部分的に冗長です。

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

2
derobert

ネットワーク接続を介してファイルを別のマシンに再転送する場合は、 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

おそらくsplitを見る必要があります。

例を含むmanページは次のとおりです。

https://ss64.com/bash/split.html

0
VaTo