java - Apache DigestUtils 似乎计算 MD5 部分错误

标签 java hash md5

今晚我正在研究一个简单的解决方案,用于在流传递时进行即时 MD5 计算。主框架立即完美运行。数据被传输并计算 MD5 哈希值。但后来我开始在 3 个不同的阶段监控 MD5 哈希值。直播前、直播中和直播后。结果让我感到惊讶。

最重要的 MD5 摘要显然是错误计算的。对于所有编码,我使用了 Apache DigestUtils 的相同方法。但我没有生成 3 倍相同的输出,而是只得到了 3 中的 2。

为了验证我的构造中不存在一般错误,我还使用了 Apache 的 (...).binary.Hex 类来对摘要进行编码。而这一次的结果和其他的结果一致。

流式传输前的MD5:9065793b048f4efee5ccddb34798ee19

流式传输后的MD5:9065793b048f4efee5ccddb34798ee19

MD5,同时由 DigestUtils 编码:95d845ff55b5918edc8d1222045dd1cb

MD5,同时由二进制编码。十六进制:9065793b048f4efee5ccddb34798ee19

这是我非常简单的代码。

第一个类是通过 main 方法启动的。 它调用 StreamForwarder 类的实例并传递测试字符串 作为输入流。就是这样。

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import org.apache.commons.codec.digest.DigestUtils;

public class StreamProvider {
    private static final byte[] streamContent;

    static {
        streamContent = "i9BjYXhrIA7FvuQ8WTIhIbgCGwfIGKfu".getBytes();
    }

    private static InputStream getStreamContent() {
        return new ByteArrayInputStream(streamContent);
    }

    public static void main(String args[]) {
        System.out.println("MD5 before streaming: " + 
            DigestUtils.md5Hex(streamContent));

        StreamForwarder streamForwarder = new StreamForwarder();
        streamForwarder.forwardStream(getStreamContent());
    }
}

StreamForwarder 将 InputStream 包装在 DigestInputStream 中,并获取 MessageDigest 的实例以在流式传输时计算 MD5 哈希值。 它调用 StreamConsumer 类的实例并传递 DigestInputStream。

import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;

public class StreamForwarder {

    public void forwardStream(InputStream is) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        DigestInputStream dis = new DigestInputStream(is, md);

        StreamConsumer streamConsumer = new StreamConsumer();
        streamConsumer.printStreamContent(dis);

        byte digest[] = md.digest();

        String digestUtilsHexString = DigestUtils.md5Hex(digest);
        String binaryHexString = new String(Hex.encodeHex(digest));

        System.out.println("MD5 while streaming encoded by DigestUtils: " + 
            digestUtilsHexString);
        System.out.println("MD5 while streaming encoded by binary.Hex: " + 
            binaryHexString);
    }
}

最后,StreamConsumer 使用 Apache 的 IOUtils 读取流。

import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;

public class StreamConsumer {

    public void printStreamContent(InputStream is) throws IOException {
        String myString = IOUtils.toString(is, "UTF-8");

        System.out.println("MD5 after streaming: " + 
            DigestUtils.md5Hex(myString.getBytes()));
    }
}

如您所见,其背后并没有什么复杂的科学原理。但 StreamForwarder.class 的输出仍然不是我所期望的 DigestUtils 的编码 HexString。

有人可以帮我解释一下为什么会发生这种情况吗?我是不是做错了什么?

提前致谢!

最佳答案

这一行的问题

String digestUtilsHexString = DigestUtils.md5Hex(digest);

您偶尔会计算摘要的摘要 - md5hex(md5(is))。你可以在 bash 中查看

$ echo -n 9065793b048f4efee5ccddb34798ee19 \
    | perl -pe 's/([0-9a-f]{2})/chr hex $1/gie' \
    | md5sum
95d845ff55b5918edc8d1222045dd1cb  -

关于java - Apache DigestUtils 似乎计算 MD5 部分错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39110379/

相关文章:

md5 - MD5Sum算法如何工作?

java - 如何使用 jackson API 重命名 JsonNode 中的字段

java.sql.SQLException : Parameter index of 9 is out of range (1, 8)

java - 使用 Java 为大文件生成 MD5 非常慢

windows - 用于非基于 SSL 的签名和加密的硬件加速

perl - 每个脚本在哈希的哈希交互约 7200 次时挂起

php - 如果字节表示小于 0x10,则从 md5() PHP 中删除 0

java - 如何在 Eclipse 中包含 Javascript 文件以解决 HTML/JSP 文件中的 Javascript 警告?

java - 如果您安装了 Google Plugin for Eclipse,是否还需要下载 App Engine Java SDK?

oracle - PL/SQL 中有散列函数吗?