【问题标题】:mysql / file hash questionmysql / 文件哈希问题
【发布时间】:2011-04-27 04:45:16
【问题描述】:

我想编写一个遍历文件树的脚本,计算每个文件的哈希值,并将哈希值与文件路径一起插入到 SQL 表中,这样我就可以查询和搜索文件完全相同的。 什么是推荐的散列函数或类似命令的工具来创建对于不同文件极不可能相同的散列? 谢谢 乙

【问题讨论】:

    标签: mysql hash duplicates directory


    【解决方案1】:

    我已经研究这个问题太久了。我正在进行第三次(希望是最后一次)重写。

    一般来说,我推荐 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 确实不会为您节省太多时间。

    【讨论】:

    • 您的工具进展如何?我一直在寻找一个简单的工具来做这件事,但是除了明显的“比较两个目录”共享软件工具之外,在网上找不到任何东西。
    • 我的程序已经能够将文件树信息加载到数据库和散列文件中;它工作得非常好。我目前正在解决用硬链接替换重复文件的问题。请注意,我的程序可能只能在 Linux 和其他类 Unix 系统上运行,因为它与 lstat() 函数填充的 stat 结构相关联。
    • 另外,它还绝对没有前端;您必须粘贴到要扫描的路径中,对于更复杂的操作,请学习如何使用 Haskell 代码。
    • @JoeyAdams 嘿,我看到这有点老了,但想知道你是否在任何地方发表过这篇文章?我会发现它真的很有用(很多人也会这样),而且我真的不想自己从头开始写一个。 Github?
    • @TolMera:感谢您的关注。实际上,我可能很快就会重新考虑它,因为我有一堆要删除重复数据的数据。尽管我可能对此进行了过度设计;您可以从 find -type f -exec sha1sum {} \; > hashes.txt 之类的内容开始分析生成的文本文件。
    【解决方案2】:

    您可以使用 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 中工作,请将斜杠更改为反斜杠。

    【讨论】:

      【解决方案3】:

      这是我想出的解决方案。我没有在 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; });
      

      我意识到我在这里没有使用过数据库。您要索引多少个文件?您是否需要将这些数据放入数据库,然后在那里搜索受骗者?

      【讨论】:

      • 谢谢 - 同时我写了一个使用 sqllite DB 的脚本
      猜你喜欢
      • 2011-05-24
      • 2011-09-12
      • 1970-01-01
      • 1970-01-01
      • 2010-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多