2010-06-03 68 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