【问题标题】:Two different MD5 on the same input?同一输入上有两个不同的MD5?
【发布时间】:2017-01-12 12:44:29
【问题描述】:
try (InputStream is = item.getInputStream())
{
    final MD5DigestCalculatingInputStream digestStream = new MD5DigestCalculatingInputStream(is);
    final byte[] bytes = IOUtils.toByteArray(digestStream);

    final String newFileName = Hex.encodeHexString(digestStream.getMd5Digest()) + "."
        + FilenameUtils.getExtension(item.getName());

    final String newFileName2 = Hex.encodeHexString(digestStream.getMd5Digest()) + "."
        + FilenameUtils.getExtension(item.getName());
}

所以在上面的代码中我得到以下结果:

newFileName = e9f08a9c181551336e58119edd23109b.png(正确)

newFileName2 = d41d8cd98f00b204e9800998ecf8427e.png(错误!)

以下所有结果也将类似于 newFileName2。正确的 newFileName 是什么并不重要,newFileName2 将始终与上面显示的值相同。真不知道这个问题是什么情况?

【问题讨论】:

  • 可能getMd5Digest 正在消费流
  • 开始比较digestStream.getMd5Digest()的后续调用,结果一样吗?

标签: java inputstream md5


【解决方案1】:

getMD5Digest 方法调用 MessageDigest.digest。

(来源) https://github.com/aws/aws-sdk-java/blob/master/aws-java-sdk-s3/src/main/java/com/amazonaws/services/s3/internal/MD5DigestCalculatingInputStream.java

MessageDigest.digest 的文档说

在进行此调用后将重置摘要。

https://docs.oracle.com/javase/7/docs/api/java/security/MessageDigest.html#digest()

因此,名字是输入流的 MD5 摘要。第二个名称是新重置摘要的 MD5,这就是为什么它总是相同的原因。

【讨论】:

  • 好的,我通过将流读入字节数组来修复它。每次我需要数据时,我都会从数组中创建一个新流,因此该值始终是正确的。感谢您的提示。
【解决方案2】:

我敢打赌,MD5DigestCalculatingInputStream.getMd5Digest() 会消耗流。这意味着第一次调用会消耗摘要,随后的调用会返回一个空摘要,这将始终产生相同的错误结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多