MessageDigest、DigestInputStream、DigestOutputStream简介

MessageDigest

MessageDigest 类为应用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。信息摘要是安全的单向哈希函数,它接收任意大小的数据,并输出固定长度的哈希值。
MessageDigest 对象开始被初始化。该对象通过使用 update 方法处理数据。任何时候都可以调用 reset 方法重置摘要。一旦所有需要更新的数据都已经被更新了,应该调用 digest 方法之一完成哈希计算。
对于给定数量的更新数据,digest 方法只能被调用一次。在调用 digest 之后,MessageDigest 对象被重新设置成其初始状态。 JDK6.0支持MD2/MD5/SHA-1(SHA)/SHA-256/SHA-384/SHA-512六种算法,名称不区分大小写。

DigestInputStream

使用读取流的方式完成摘要更新,调用on(boolean on)方法开启和关闭摘要功能。如果on(false),则DigestInputStream就变成了一般的输入流。默认摘要功能是开启的,如果开启了摘要功能,调用read方法时,将调用MessageDigest 类的update方法更新摘要。


DigestOutputStream

使用写入流的方式完成摘要更新,调用on(boolean on)方法开启和关闭摘要功能。如果on(false),则DigestOutputStream就变成了一般的输出流。默认摘要功能是开启的,如果开启了摘要功能,调用write方法时,将调用MessageDigest 类的update方法更新摘要。

示例

    public static void main(String[] args) throws Exception {
        byte[] bytes = "测试".getBytes();
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        messageDigest.update(bytes);

        MessageDigest messageDigest1 = MessageDigest.getInstance("MD5");
        DigestInputStream digestInputStream = new DigestInputStream(new ByteArrayInputStream(bytes), messageDigest1);
        digestInputStream.read(bytes, 0, bytes.length);
        System.out.println(MessageDigest.isEqual(messageDigest.digest(), digestInputStream.getMessageDigest().digest()));
        digestInputStream.close();

        MessageDigest messageDigest2 = MessageDigest.getInstance("MD5");
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        System.out.println(byteArrayOutputStream.toString());
        DigestOutputStream digestOutputStream = new DigestOutputStream(byteArrayOutputStream, messageDigest2);
        digestOutputStream.write(bytes, 0, bytes.length);
        digestOutputStream.getMessageDigest().digest();
        System.out.println(byteArrayOutputStream.toString());
        digestOutputStream.flush();
        digestOutputStream.close();
    }

输出
true

测试



### Java 中使用 `DigestInputStream` 计算大文件 MD5 值的示例 `DigestInputStream` 是 Java 提供的一个输入流类,它允许在读取数据的同时自动更新指定的消息摘要对象(如 MD5)。这种方法非常适合于处理大文件,因为它不需要将整个文件加载到内存中。 #### 使用 `DigestInputStream` 实现大文件 MD5 计算 下面是一个完整的代码示例,展示如何利用 `DigestInputStream` 来计算大文件的 MD5 值: ```java import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.*; public class LargeFileMD5WithDigestInputStream { public static String calculateMD5UsingDigestInputStream(Path filePath) throws IOException, NoSuchAlgorithmException { MessageDigest messageDigest = MessageDigest.getInstance("MD5"); try (InputStream inputStream = Files.newInputStream(filePath); DigestInputStream digestInputStream = new DigestInputStream(inputStream, messageDigest)) { byte[] buffer = new byte[8192]; // 设置缓冲区大小为 8KB while (digestInputStream.read(buffer) != -1); // 需要完全读取以确保消息摘要被正确更新 return bytesToHex(messageDigest.digest()); } } private static String bytesToHex(byte[] hashBytes) { StringBuilder hexString = new StringBuilder(2 * hashBytes.length); for (byte b : hashBytes) { String hex = Integer.toHexString(0xff & b); if (hex.length() == 1) { hexString.append('0'); } hexString.append(hex); } return hexString.toString(); } public static void main(String[] args) { Path path = Paths.get("path/to/largefile.txt"); // 替换为目标文件路径 try { System.out.println(calculateMD5UsingDigestInputStream(path)); } catch (Exception e) { e.printStackTrace(); } } } ``` 在此代码中,创建了一个基于给定文件路径的 `InputStream` 并将其封装在一个新的 `DigestInputStream` 对象里。随后通过不断调用 `read()` 方法直到返回 `-1` 表明已到达文件末尾[^4]。最后从原始的 `MessageDigest` 实例提取出最终的结果并转换成十六进制表示形式输出。 --- #### 关键点解析 - **为何选择 `DigestInputStream`?** 直接使用 `MessageDigest.update(byte[], int, int)` 方法虽然也可以达到目的,但每次都需要手动传递缓冲区及其偏移量和长度参数;相比之下,`DigestInputStream` 自动管理这些细节,简化了开发者的负担[^1]。 - **缓冲区大小的选择** 同样地,这里也采用了常见的 8 KB 缓冲区尺寸作为折衷方案,在多数情况下都能取得不错的性能平衡[^5]。 - **异常处理的重要性** 在实际应用过程中应当更加细致地对待可能出现的各种异常情况,比如文件不存在、权限不足等问题都应该有相应的捕获与反馈机制[^3]。 --- #### 性能对比分析 相较于传统方式逐一调用 `update()` 函数的方法来说,采用 `DigestInputStream` 不仅让程序结构更为清晰简洁,而且由于其内部实现了优化后的循环逻辑,往往还能带来轻微的速度提升[^2]。 --- #### 安全提示 需要注意的是,尽管本案例专注于介绍如何高效地计算大文件的 MD5 校验值,但在涉及安全性较高的场景下(例如身份认证或数字签名),建议选用更强大的算法如 SHA-256 等代替相对脆弱的 MD5[^7]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值