2011-06-30 60 views
3

會有什麼(對於性能和存儲空間的最佳)存儲在Java的MD5和文件(或常規)的最有效的方式對象考慮以下使用案例:最有效的方法來存儲java對象大十六進制數字(MD5)

  1. 我需要與成千上萬的其他md5總和進行比較。
  2. 我可能需要這些信息存儲在HSQLDB,使記錄可以基於MD5
  3. 可以存儲在Map的作爲鍵

我試圖避免把它作爲String拉/ group by因爲字符串比較會花費更多,佔用更多空間。 BigInteger(string,radix)會更有效率嗎?另外,如果堅持數據庫,應該選擇哪種數據類型?

回答

4

創建一個包裝了byte[]並提供沒有突變的類。如果你想用它作爲地圖中的一個鍵,那麼它需要是可比較的,或者有一個哈希碼。使用byte[],您可以更輕鬆地從前32位計算簡單哈希碼。

+1

謝謝你的回答。與常規'新的BigInteger(1,摘要)的ToString(16).padLeft(32,「0」)'可以生成從'字節散列[]'但不知道這是「有效的」照顧。如果我必須在BigInt和String之間進行選擇,你會有什麼建議?我問這是因爲這只是一個常規腳本,創建一個包裝可能是矯枉過正的(如果它沒有巨大的性能優勢)。 – kunal

+1

@kunal,如果被迫在bigint和string之間進行選擇,我會選擇BigInteger。當您將一系列十六進制數字作爲字符串進行天真存儲時,字符串不具有空間效率。你可以將代碼打包成UTF-16代碼單元,但沒有任何理由去解決問題。所有這些工作所節省的最多成本是BigBenteger的16b。 –

+0

再次感謝您的回答。正如@erickson提到的那樣,將它存儲很長時間呢? – kunal

0

如果您需要執行大量比較,則可以將MD5值存儲爲2 long整數,這樣您只需執行至多4個邏輯操作即可檢查另一個MD5值。

基本上,提供一類,將接受的輸入,原始摘要數據作爲byte[]並使用

ByteBuffer bb = ByteBuffer.wrap(digestData); 
long[] bits = new long[] { 
    bb.getLong(), 
    bb.getLong() 
}; 

與另一long[] MD5陣列進行比較以

boolean eq = ((bits[0]^otherBits[0]) | (bits[1]^otherBits[1])) == 0); 

重構MD5
ByteBuffer bb = ByteBuffer.allocate(16); 
bb.putLong(bits[0]); 
bb.putLong(bits[1]); 

byte[] digestData = new byte[16]; 
bb.get(digestData); 

:我不建議對byte[]轉換成long[]每一個比較,這簡直是如何存儲消化比較。最後一個重建片段是可選的,您應該保留數據爲byte[]並僅比較long[]陣列。在數據庫中,將數據存儲爲32字節的十六進制值。

+0

-1:無論JVM如何,long總是64位。而且沒有必要進行所有這些轉換。 Long.SIZE是一個常數。檢查它沒有意義。只需將它作爲一個字節數組存儲並使用java.util.Arrays.equals(byte [],byte [])。 –

+0

嗯...我一定是被我的C班污染,然後......修復答案。 –

+0

@JB Nizel,問題的性能問題,並檢查Arrays.equals(byte [],byte [])比執行我建議的檢查效率低。 API的存在是爲了方便,雖然我通常在大多數情況下建議使用Java API,但這裏並不是這種情況。 –

1

對於Java的比對速度,將其存儲爲兩個long值將可能是最快的。對於持久性來說,如果數據庫和持久性工具支持它,存儲爲字節數組是最有意義的。否則,存儲爲十六進制或基於64編碼的文本是相當常見的,並且可以與訪問相同數據庫的其他應用程序良好地互操作。

相關問題