2010-06-03 66 views
1

我是計算機科學的學生,我們必須在我們的課程中使用BaseX(純Java OSS XML數據庫)。雖然通過代碼瀏覽我發現下面的代碼:BaseX XML數據庫代碼

/** 
    * Returns a md5 hash. 
    * @param pw password string 
    * @return hash 
    */ 
    public static String md5(final String pw) { 
    try { 
     final MessageDigest md = MessageDigest.getInstance("MD5"); 
     md.update(Token.token(pw)); 
     final TokenBuilder tb = new TokenBuilder(); 
     for(final byte b : md.digest()) { 
     final int h = b >> 4 & 0x0F; 
     tb.add((byte) (h + (h > 9 ? 0x57 : 0x30))); 
     final int l = b & 0x0F; 
     tb.add((byte) (l + (l > 9 ? 0x57 : 0x30))); 
     } 
     return tb.toString(); 
    } catch(final Exception ex) { 
     Main.notexpected(ex); 
     return pw; 
    } 
    } 

(來源:https://svn.uni-konstanz.de/dbis/basex/trunk/basex/src/main/java/org/basex/util/Token.java

只是出於興趣:發生了什麼呢?爲什麼在MD5之後進行這些字節操作?文檔字符串是說它返回一個MD5散列......是嗎?

回答

5

我沒有查找所用類的定義,但字節操作似乎將返回的字節數組編碼爲十六進制字符串。

for(final byte b : md.digest()) { 
    // get high 4 bytes of current byte 
    final int h = b >> 4 & 0x0F; 
    // convert into hex digit (0x30 is '0' while 0x57+10 is 'a') 
    tb.add((byte) (h + (h > 9 ? 0x57 : 0x30))); 
    // the same for the bottom 4 bits 
    final int l = b & 0x0F; 
    tb.add((byte) (l + (l > 9 ? 0x57 : 0x30))); 
} 

這就是爲什麼使用幻數是不好的一個很好的例子。舉個例子,我真的不記得0x57 + 10是'a'的ASCII/Unicode代碼點,而沒有在Python解釋器中檢查它。

+0

THX的澄清 – 2010-06-05 12:29:51

0

我猜Matti是正確的 - 因爲md.digest()返回一個byte [],而BaseX使用Tokens來支持Strings(TokenBuilder)。 所以從md.digest()到String的轉換是通過Digest-Hex到Token的轉換完成的。

不完全容易閱讀,但非常類似於Apache Commons在其Codec Library 中獲取md5哈希值的字符串值。

0

這是爲什麼使用幻數不好的一個很好的例子。

嗯,這是一個核心方法,它不應該被別人修改 - 這看起來是最有效的方法。但是,真的,文件可能會更好。談到核心方法,這是值得看這樣的代碼Integer.getChars():

http://www.docjar.com/html/api/java/lang/Integer.java.html

+0

無論你的代碼的「核心」是如何,它最終會被某人(讀*喜歡剛剛*),因此它應該是可讀的。通過以更易於閱讀的格式編寫表達式,或者至少爲可憐的讀者發表評論,不會犧牲效率。 – 2010-06-05 12:35:29