如何在不捕获NoSuchAlgorithmException的情况下使用Java MD5 MessageDigest?

12
在Java中,如果我想计算一个MD5摘要,我需要注意可能出现的异常:
try {
   MessageDigest md = MessageDigest.getInstance("MD5");
   // Do stuff
} catch (NoSuchAlgorithmException e) {
   // Can't happen...
}

然而,根据JVM规范,必须支持MD5,因此不应该抛出异常。是否存在其他访问模式,使我能够编写更加优雅的代码?


8
不好意思,不行。在未来的漫长岁月里,Java的受检异常将会是一个束缚。 - Seva Alekseyev
+1. 我经常想知道是否有更好的方法来处理那些抛出UnsupportedEncodingException异常的方法,因为我只需要强制支持的UTF-8编码。(到目前为止,我的解决方案是使用Throwables.propagate,这还不错,但仍然有点麻烦。) - ruakh
1
@ruakh:你可以在Java 7及更高版本中使用StandardCharsets.UTF_8。 :) - MikeD
2
@MikeD:哦,不错,谢谢!所以我想这也回答了你的问题:优雅的访问模式是“等待几个JDK版本,直到它们添加一个更具体的方法来规避问题,然后调用它”。你的延迟要求是什么? :-) - ruakh
2个回答

4

您可以使用common.apacheDigestUtils代替MessageDigest。这很容易使用,不需要像MessageDigest那样采取如此繁琐的过程来摘要数据。

DigestUtils.md5("String to digest");

请查看这个类并参考文档


4
您可以忘记Java实现,使用Guava的:http://docs.guava-libraries.googlecode.com/git-history/v11.0/javadoc/com/google/common/hash/Hashing.html#md5()。在Java中,您不能完全忽略Checked Exception。您可以捕获它,或者在方法上添加"throws Exception",或者获取一个不那么严谨的库。对我来说,下面的Guava变体以最少的仪式客户惊喜地完成了工作。
// Its my problem, yuk...
public byte[] md5TheHardWay( String s ) {
    try {
        MessageDigest md = MessageDigest.getInstance( "MD5" );
        // Do stuff
        byte[] result = md.digest( s.getBytes() );
        return result;
    } catch ( NoSuchAlgorithmException e ) {
        // Can't happen...
        e.printStackTrace();
    }
    return null;
}

// Its your problem, yuk...
public byte[] md5ItsYourProblemClient( String s ) throws NoSuchAlgorithmException {
    MessageDigest md = MessageDigest.getInstance( "MD5" );
    // Do stuff
    byte[] result = md.digest( s.getBytes() );
    return result;
}

// Its no problem...I like Guava.
public byte[] md5ThroughGuava( String s ) {
    HashFunction md = Hashing.md5();
    HashCode code = md.hashBytes( s.getBytes() );
    return code.asBytes();
}

浏览Guava代码时,我们会发现它是如何做到这一点的。 毫无疑问,Guava库的编写者采用了“这是我的问题,呸......”的方式,捕获了受检异常并将其转换为RuntimeException。这种做法非常聪明和有效。

// an excerpt from the Guava sourcecode
private static MessageDigest getMessageDigest(String algorithmName) {
  try {
    return MessageDigest.getInstance(algorithmName);
  } catch (NoSuchAlgorithmException e) {
    throw new AssertionError(e);
  }
}

我提到过我喜欢番石榴吗?我超爱番石榴。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接