2011-07-13 19 views
1

我開發一個web應用程序(使用Java EE 6 GF 3.1),允許用戶上傳PDF文件。由於這是一個封閉的小型社區,因此上傳的文件已存在於系統中的機會很多。我不能僅僅檢查名稱是否存在重複,因爲它顯然是不夠的。我正在考慮散列整個文件並將條目存儲在數據庫中。這是可行的,以及如何實現這一目標?如果不是,那麼什麼是更好的方法。如何散列文件,以確定如果我已經看到它或不

+1

聽起來很合理。文件上傳不應該太常見,並且散列計算只能執行一次,而不是計算密集型的。 –

回答

4

考慮使用校驗和。

這是http://www.exampledepot.com/egs/java.util.zip/CalculateChecksum.html

byte[] bytes = "some data".getBytes(); 

// Compute Adler-32 checksum 
Checksum checksumEngine = new Adler32(); 
checksumEngine.update(bytes, 0, bytes.length); 
long checksum = checksumEngine.getValue(); 

// Compute CRC-32 checksum 
checksumEngine = new CRC32(); 
checksumEngine.update(bytes, 0, bytes.length); 
checksum = checksumEngine.getValue(); 

// The checksum engine can be reused again for a different byte array by calling reset() 
checksumEngine.reset(); 

編輯

注意校驗絕對不能告訴你,如果兩個文件是不同的,但是他們是非常有用的。

如果兩個文件相同,他們具有相同的校驗和。

因此,如果校驗和不同,你知道絕對的文件不同。

但是兩個不同的文件有時也可能具有相同的校驗和。

所以使用這種方式是先計算校驗 - 如果有差別,這些文件是不同的。如果它們是相同的,則必須進行逐字節的比較。當然這比較慢,但不會經常發生。

還要注意這一切適用於哈希碼爲好。

+0

文件校驗和是否保證文件的唯一性? –

+0

+1在這裏沒有提示安全哈希,CRC32更快,安全性不是問題的本質。 – emboss

+0

@哈利 - 是和不是。是的,校驗和保證唯一性:如果兩個文件產生不同的校驗和,則文件是不同的。但是相反的情況並非如此:兩個不同的文件可能有不同的校驗和(散列或其他任何表徵方法的結果都小於原始值)。 – CPerkins

2

您的解決方案非常優雅。計算文件內容的散列(MD5可能足以啓動)並將其用作數據庫中的主鍵。您可以將文件保存在數據庫中,也可以保存在外部(對此有很多爭議)。

下一次有人上載文件,計算哈希值,檢查數據庫,保存,如果不存在。

2

是的,這是可行的。事實上,這就是P2P程序識別文件的方法。

使用任何加密哈希算法(MD5,SHA-1等)

Java有使用MessageDigest類散列支持。

但是請注意,這樣可以避免存儲重複文件,但它不會阻止用戶上傳文件:只有在服務器端,您才能訪問文件內容並對其進行哈希處理,除非您使用具有訪問本地文件權限的applet或webstart應用程序。

1

當然,這是可行的,可以使用MessageDigest類來做到這一點。例如:

InputStream is = // input stream of the uploaded file 
byte[] buffer = new byte[1024]; 
byte[] digest; 
try { 
    MessageDigest md = MessageDigest.getInstance("MD5"); 

    for (int count = is.read(buffer); count != -1; count = is.read(buffer)) { 
     md.update(buffer, 0, count); 
    } 

    digest = md.digest(); 
    // store digest as needed, possibly Base64 encode first 
} 
catch (NoSuchAlgorithmException e) { 
    // handle 
} 
+0

文件上的MD5散列是否保證唯一性 - >如果兩個散列不同,則兩個文件不同,反之亦然。如果不是這樣,那麼從Md5切換到SHA-256將有助於增加唯一性的機會? –

+0

它沒有_guarantee_唯一性,沒有散列函數可以做到這一點,但碰撞的機率很低。 SHA的衝突機率更低,但計算SHA哈希需要的時間比計算MD5哈希需要的時間更長。話雖如此,CRC可能是一個更好的選擇,正如CPerkins所指出的那樣,因爲你不需要安全的哈希。 –

1

在過去,我已經使用蒂莫西·W^Macinta的(可能是這樣用戶@Tim Macinta)"Fast MD5 Implementation"

最簡單的例子是:

// imports: java.io.File and com.twmacinta.util.MD5; 

String hash = MD5.asHex(MD5.getHash(new File(filename))); 

此實用程序還必須使用本機庫,以提高性能的能力。

+0

文件上的MD5散列是否保證唯一性 - >如果兩個散列不同,則兩個文件不同,反之亦然。如果不是這樣,那麼從Md5切換到SHA-256將有助於增加唯一性的機會? –

相關問題