小易说IT 小易说IT

Java MD5 示例代码

说明:JDK 自带 java.security.MessageDigestMD5 仅用于摘要校验,不要用来存储密码。 输出结果为小写 32 位 MD5 字符串。

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Util {

    /**
     * 计算字符串的MD5,返回小写32位十六进制字符串
     * @param source 原始字符串
     * @return md5摘要
     */
    public static String getMD5(String source) {
        if (source == null || source.isEmpty()) {
            return null;
        }
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = md5.digest(source.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : bytes) {
                // 转成无符号8位整数
                int val = b & 0xff;
                String hex = Integer.toHexString(val);
                if (hex.length() == 1) {
                    sb.append("0");
                }
                sb.append(hex);
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            // MD5算法一定存在,理论不会进入此异常
            throw new RuntimeException("MD5算法不存在", e);
        }
    }

    /**
     * 计算字节数组MD5
     */
    public static String getMD5(byte[] data) {
        if (data == null || data.length == 0) {
            return null;
        }
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = md5.digest(data);
            StringBuilder sb = new StringBuilder();
            for (byte b : bytes) {
                int val = b & 0xff;
                String hex = Integer.toHexString(val);
                if (hex.length() == 1) {
                    sb.append("0");
                }
                sb.append(hex);
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5算法不存在", e);
        }
    }

    public static void main(String[] args) {
        String testStr = "hello world";
        String md5Result = getMD5(testStr);
        System.out.println("原始字符串:" + testStr);
        System.out.println("MD5结果:" + md5Result);
        // hello world md5: 5eb63bbbe01eeed093cb22bb8f5acdc3
    }
}

文件 MD5 版本(常用,校验文件完整性)

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class FileMD5Util {
    public static String getFileMD5(File file) throws IOException {
        if (!file.exists() || file.isDirectory()) {
            return null;
        }
        try (FileInputStream fis = new FileInputStream(file)) {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] buffer = new byte[8192];
            int len;
            while ((len = fis.read(buffer)) != -1) {
                md5.update(buffer, 0, len);
            }
            byte[] digest = md5.digest();
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                int val = b & 0xff;
                String hex = Integer.toHexString(val);
                if (hex.length() == 1) {
                    sb.append("0");
                }
                sb.append(hex);
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5算法不存在", e);
        }
    }

    public static void main(String[] args) throws IOException {
        File file = new File("test.txt");
        String md5 = getFileMD5(file);
        System.out.println("文件MD5:" + md5);
    }
}

重要提醒

  1. 字符串编码问题:source.getBytes() 默认使用系统编码,生产建议显式指定 UTF-8

byte[] bytes = source.getBytes(java.nio.charset.StandardCharsets.UTF_8);
  1. 安全警告:MD5 不可用于密码存储、防恶意篡改,密码存储推荐 BCrypt / Argon2id

  2. 如果需要大写 MD5,把 Integer.toHexString(val) 结果 .toUpperCase() 即可。


本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。

原文链接 https://www.yijunzhao.cc/archives/java-md5-example-code

欢迎访问 https://www.yijunzhao.cc/

https://www.yijunzhao.cc/