1

我是计算机科学专业的学生,​​我们必须在其中一门课程中使用 BaseX(纯 Java OSS 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 哈希......是吗?

4

3 回答 3

4

我没有查找所用类的定义,但字节操作似乎将返回的字节数组编码为一串十六进制字符。

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 解释器中检查它。

于 2010-06-03T13:48:09.443 回答
1

我猜 Matti 是对的——因为 md.digest() 返回一个 byte[] 并且 BaseX 使用 Tokens 而不是 Strings(因此是 TokenBuilder)。所以从 md.digest() 到 String 的转换是通过 Digest-Hex 到 Token 的转换来完成的。

不是很容易阅读,但与 Apache Commons 在其编解码器库 中获取 md5 哈希的字符串值非常相似。

于 2010-06-03T22:12:10.950 回答
0

这是为什么使用幻数不好的一个很好的例子。

嗯,这是一个核心方法,不应该被其他人修改——这看起来是最有效的方法。但是,确实,文档可能会更好。谈到核心方法,值得看一下 Integer.getChars() 之类的代码:

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

于 2010-06-04T11:28:11.797 回答