2011-02-16 90 views
4

我需要計算一個字符串的哈希碼並將其存儲到一個'長'變量中。生成長MD5或SHA1哈希碼(64位)

MD5和SHA1產生的散列碼長於64位(MD5 - 128位,SHA1 - 160位)。

想法任何一個?

乾杯,

多倫

+2

一個想法:不。你爲什麼認爲你需要這樣做? – 2011-02-16 16:29:24

+0

@larsmans可能是因爲他們希望將它用作非加密散列作爲弱檢查,以確保它們不會生成多個相同的事物,並且不希望存儲大量128位字符的十六進制字符串,有點哈希。 – 2014-06-13 11:30:15

回答

3

您可以截斷哈希和使用只是第64位。哈希將稍微不那麼強壯,但前64位仍然極有可能是唯一的。

對於散列的大多數用途來說,這是一種常見且完全可以接受的做法。

您還可以將完整散列存儲爲兩個64位整數。

+1

請注意,如果安全性很重要,MD5被認爲是一個非常糟糕的選擇。儘管存儲非祕密數據的哈希值仍然很好。 – 2011-02-16 16:09:10

0

將這些位異或?例如。對於MD5,位0-63,異或位64-127,瞧,64位。這會給你一個較弱的散列,檢查你是否可以接受。

(還,除非你的環境是非常限制 - 例如嵌入式設備 - 還有的「你爲什麼需要縮短了嗎?」一題)

1

FNV Hash是很容易實現。我們將其擴展到64位,它工作得很好。使用它比計算MD5或SHA1快得多,然後截斷結果。但是,我們並不依賴它來獲取密碼函數 - 僅用於散列表等。在FNV

更多信息,與源代碼和詳細的解釋:http://isthe.com/chongo/tech/comp/fnv/

0

您也可以播放各種的哈希算法與FooBabel Hasher

1

我使用這個(JAVA):

public class SimpleLongHash { 
    final MessageDigest md; 
    // 
    public SimpleLongHash() throws NoSuchAlgorithmException { 
     md = MessageDigest.getInstance("MD5"); 
    } 
    // 
    public long hash(final String str) { 
     return hash(str.getBytes()); 
    } 
    public long hash(final byte[] buf) { 
     md.reset(); 
     final byte[] digest = md.digest(buf); 
     return (getLong(digest, 0)^getLong(digest, 8)); 
    } 
    // 
    private static final long getLong(final byte[] array, final int offset) { 
     long value = 0; 
     for (int i = 0; i < 8; i++) { 
      value = ((value << 8) | (array[offset+i] & 0xFF)); 
     } 
     return value; 
    } 
} 
0

由於前64位與後64位之間的異或而導致衝突的概率是多少?