按 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— 根據校驗和跳過,而不是檔案大小/運行時間。預設情況下,rsync 會最佳化並跳過大小和運行時間匹配的傳輸。-c強制它計算校驗和(就 I/O 而言,這是一項昂貴的操作)。請注意,這是基於區塊的校驗和(除非您告訴它僅執行整個檔案),並且它只會傳輸損壞的區塊。區塊大小是自動選擇的,但可以被覆蓋-B(我懷疑有任何理由這樣做)。
  • -v— 詳細,將提供一些詳細資訊(正在處理哪個文件)
  • -P— 開啟兩個部分檔案(因此,如果完成一半,它不會放棄工作)和進度條。
  • --inplace— 更新現有文件,而不是臨時文件(隨後將取代原始文件)。讓您免於擁有 200GB 的臨時檔案。也意味著部分文件,因此這-P是部分冗餘的。

順便說一句:我不確定你是如何進行原始傳輸的,但如果它是 sftp/scp,那麼有些事情就非常錯誤了——它們完全防止網路上的任何損壞。你確實應該找出原因。 RAM 有缺陷是一種相對常見的情況。

答案2

如果您想透過網路連線將檔案重新傳輸到另一台機器,使用rsync

如果您想了解差異在哪裡,最簡單的方法是將兩個版本放在同一台電腦上。如果您因為頻寬太昂貴而不想這樣做,可以透過以下方法檢查檔案區塊。

此方法依賴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

這是包含範例的手冊頁:

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

相關內容