2010-09-25 58 views
2

我想編寫一個遍歷文件樹的腳本,爲每個文件計算一個散列,並將散列和文件路徑一起插入SQL表中,這樣我就可以查詢和搜索相同的文件。 什麼是推薦的散列函數或類似工具的命令來創建對於不同文件極不相同的散列? 感謝 乙mysql /文件散列問題

回答

0

你可以使用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改變工作斜槓反斜槓。

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安全,但CPU功耗約爲2.5倍。但是,I/O往往是瓶頸(CPU緊隨其後),所以使用MD5而不是SHA1確實不會節省您很多時間。

+0

你與你的工具有多遠?我一直在尋找一個簡單的工具,可以做到這一點,但除了顯而易見的「比較兩個目錄」共享工具之外,無法在網上找到任何東西。 – b20000 2010-09-26 17:53:15

+0

我的程序已經能夠將文件樹信息加載到數據庫和哈希文件中;它非常出色。我目前正在研究用硬鏈接替換重複文件的問題。請注意,我的程序可能僅適用於Linux和其他類Unix系統,因爲它與['lstat()']填充的stat結構相關聯(http://linux.die.net/man/2/lstat )功能。 – 2010-09-26 18:29:59

+0

此外,它絕對沒有前端;你將不得不粘貼你想要掃描的路徑,並且爲了更復雜的操作,學習如何使用Haskell代碼。 – 2010-09-26 18:36:29

0

這是我想出的解決方案。我沒有做這一切在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

謝謝 - 我寫了一個腳本,同時使用sqllite DB – b20000 2011-04-27 05:59:58