按 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

相关内容