mysql / file hash question - PullRequest
       23

mysql / file hash question

3 голосов
/ 26 сентября 2010

Я хотел бы написать скрипт, который обходит дерево файлов, вычисляет хэш для каждого файла и вставляет хэш в таблицу SQL вместе с путем к файлу, чтобы я мог затем запрашивать и искать файлы, которые идентичны. Какой будет рекомендованная хеш-функция или инструмент, подобный команде, для создания хешей, которые вряд ли будут идентичны для разных файлов? Спасибо B

Ответы [ 3 ]

1 голос
/ 26 сентября 2010

Я слишком долго работал над этой проблемой. Я на третьем (и, надеюсь, последнем) переписывании.

Вообще говоря, я рекомендую SHA1, потому что у него нет известных коллизий (тогда как коллизии MD5 можно обнаружить за минуты ), а SHA1 не является узким местом при работе с жесткими дисками. Если вы одержимы стремлением заставить вашу программу работать быстро при наличии твердотельного накопителя, либо переходите на MD5, либо тратите дни и дни своего времени, пытаясь найти способ распараллеливания операции. В любом случае, не распараллеливайте хеширование , пока ваша программа не сделает все, что вам нужно.

Также я рекомендую использовать sqlite3. Когда я сделал хэш-файл моего программного хранилища в базе данных PostgreSQL, вставки в базу данных стали настоящим узким местом. Конечно, я мог бы попытаться использовать COPY (я забыл, если бы я сделал или нет), и я предполагаю, что это было бы достаточно быстро.

Если вы используете sqlite3 и выполняете вставки в блоке BEGIN / COMMIT, вы, вероятно, просматриваете около 10000 вставок в секунду при наличии индексов. Однако то, что вы можете сделать с полученной базой данных, делает все это стоящим. Я сделал это с около 750000 файлов (85 ГБ). Вся операция вставки и хеширования SHA1 заняла менее часа, и она создала файл sqlite3 размером 140 МБ. Однако мой запрос на поиск дубликатов файлов и их сортировку по идентификатору занимает менее 20 секунд.

В целом, использование базы данных хорошо, но обратите внимание на накладные расходы. SHA1 безопаснее, чем MD5, но потребляет примерно в 2,5 раза больше ресурсов процессора. Тем не менее, ввод-вывод является узким местом (процессор занимает второе место), поэтому использование MD5 вместо SHA1 действительно не сэкономит вам много времени.

0 голосов
/ 27 апреля 2011

Вот решение, которое я выяснил.Я не делал всего этого в 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; });

Я понимаю, что здесь я не использовал базы данных.Сколько файлов вы собираетесь индексировать?Вам нужно поместить эти данные в базу данных, а затем искать там дуплики?

0 голосов
/ 26 сентября 2010

Вы можете использовать хэш 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, измените косую черту на обратную.

...