语境:
md5sum
我有一个大容量的 TB 驱动器,里面有各种类型的大型媒体文件、ISO 映像文件等。考虑到速度/性能,我想使用第一个兆字节来验证其内容。
您可以像这样创建总数:
FILE=four_gig_file.iso
SUM=$(head -c 1M "$FILE" | md5sum)
printf "%s *%s\n" ${SUM%-} "$FILE" >>test.md5
由于第一个兆字节的签名与整个文件的签名不同,您如何验证这一点?
我在其他语言中见过这种做法,但我想知道如何在猛击。我试验过md5sum -c
涉及管道和其他东西的各种排列组合。
除了使用之外md5sum -c
,您是否必须将哈希值重新计算到新文件中,然后对它们进行“差异”?
您可以使用
find /directory/path/ -type f -print0 | xargs -0 md5sum blah blah
处理大量文件。
附言:Rsync 不是一个选项
更新 2:目前情况是这样的——
使用 head、find 和 md5sum;然后可以相当快地从源目录创建一个文件,然后在目标上计算后在另一端使用 diff 检查它。有没有巧妙的单行代码或脚本可以做到这一点?
答案1
仅通过对文件的第一个兆字节进行采样来验证内容可能无法检测出某些较大的文件是否以某种方式被破坏、损坏或更改。原因是您只向哈希算法提供了一兆字节的数据,而其他数百兆字节的数据可能存在偏差。即使一个位的位置错误,也会给出不同的签名。
如果您想要验证数据完整性,最好使用 CRC32 算法。它比 MD5 更快。虽然可以伪造/修改文件以使其看起来具有正确的 CRC32 签名,但随机损坏的位不太可能做到这一点。
更新:
下面是一行代码,用于对每个文件执行基于 1MB 的 md5 校验:
find ./ -type f -print0 | xargs -0 -n1 -I{} sh -c "echo '{}' >> output.md5 && head -c 1M '{}' | md5sum >> output.md5"
如果您愿意,可以将 md5sum 替换为 cksum。请注意,我选择在输出中包含文件名。这是因为当您没有将整个文件提供给 md5sum 时,文件名字符串不会被传递。
答案2
稍微修改了一下解决方案/示例,使用 find -size 参数来限制仅大于 10M 的文件,并从文件的前 1M 和后 1M 部分计算 md5sum。
find . -type f -a -size +10M -print0 | xargs -0 -n1 -I{} sh -c 'echo "$( (head -c 1M '{}'; tail -c 1M '{}' ) | md5sum) {} "'