【发布时间】:2011-04-27 04:45:16
【问题描述】:
我想编写一个遍历文件树的脚本,计算每个文件的哈希值,并将哈希值与文件路径一起插入到 SQL 表中,这样我就可以查询和搜索文件完全相同的。 什么是推荐的散列函数或类似命令的工具来创建对于不同文件极不可能相同的散列? 谢谢 乙
【问题讨论】:
标签: mysql hash duplicates directory
我想编写一个遍历文件树的脚本,计算每个文件的哈希值,并将哈希值与文件路径一起插入到 SQL 表中,这样我就可以查询和搜索文件完全相同的。 什么是推荐的散列函数或类似命令的工具来创建对于不同文件极不可能相同的散列? 谢谢 乙
【问题讨论】:
标签: mysql hash duplicates directory
我已经研究这个问题太久了。我正在进行第三次(希望是最后一次)重写。
一般来说,我推荐 SHA1,因为它没有已知的冲突(而 MD5 冲突can be found in minutes),并且 SHA1 在使用硬盘时不会成为瓶颈。如果您痴迷于让程序在存在固态驱动器的情况下快速运行,那么要么使用 MD5,要么浪费数天的时间来弄清楚如何并行化操作。在任何情况下,在您的程序完成您需要做的所有事情之前,不要并行化散列。
另外,我推荐使用 sqlite3。当我在 PostgreSQL 数据库中创建程序存储文件哈希时,数据库插入是一个真正的瓶颈。诚然,我本可以尝试使用 COPY(我忘记了我是否使用过),而且我猜这会相当快。
如果您使用 sqlite3 并在 BEGIN/COMMIT 块中执行插入,那么在存在索引的情况下,您可能会看到每秒大约 10000 次插入。但是,您可以对生成的数据库做些什么,这一切都是值得的。我用大约 750000 个文件 (85 GB) 做到了这一点。整个插入和 SHA1 哈希操作只用了不到一个小时,它创建了一个 140MB 的 sqlite3 文件。但是,我查找重复文件并按 ID 对它们进行排序的查询运行时间不到 20 秒。
总之,使用数据库是好的,但请注意插入开销。 SHA1 比 MD5 更安全,但需要大约 2.5 倍的 CPU 功率。但是,I/O 往往是瓶颈(CPU 紧随其后),因此使用 MD5 代替 SHA1 确实不会为您节省太多时间。
【讨论】:
lstat() 函数填充的 stat 结构相关联。
find -type f -exec sha1sum {} \; > hashes.txt 之类的内容开始分析生成的文本文件。
您可以使用 md5 哈希或 sha1
function process_dir($path) {
if ($handle = opendir($path)) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
if (is_dir($path . "/" . $file)) {
process_dir($path . "/" . $file);
} else {
//you can change md5 to sh1
// you can put that hash into database
$hash = md5(file_get_contents($path . "/" . $file));
}
}
}
closedir($handle);
}
}
如果您在 Windows 中工作,请将斜杠更改为反斜杠。
【讨论】:
这是我想出的解决方案。我没有在 PHP 中完成所有这些操作,但如果您愿意,这很容易做到:
$fh = popen('find /home/admin -type f | xargs sha1sum', 'r');
$files = array();
while ($line = fgets($fh)) {
list($hash,$file) = explode(' ', trim($line));
$files[$hash][] = $file;
}
$dupes = array_filter($files, function($a) { return count($a) > 1; });
我意识到我在这里没有使用过数据库。您要索引多少个文件?您是否需要将这些数据放入数据库,然后在那里搜索受骗者?
【讨论】: