• 别找了,Java生成MD5值直接用轮子就好了


    先说说 Java 生成 MD5 的原理

    Java 生成 MD5 值,本质上都是通过MessageDigest类来实现的。

    一共分为四步:

    1. 通过MessageDigest.getInstance("MD5")方法来获取一个MessageDigest实例。这是一个工厂方法,你也可以创建其他算法的实例。

    2. 通过update方法来传入字节数组,并根据该数组更新摘要。

    3. 使用digest()计算并返回byte[]格式的哈希值,并重置摘要。

    4. 用各种办法将byte[]格式的哈希值转为16进制字符串。

    翻译成代码如下:

    public String getMD5String(String s) throws NoSuchAlgorithmException {
        // 创建md5实例
        MessageDigest messagedigest = MessageDigest.getInstance("MD5");
        // 更新摘要
        messagedigest.update(s.getBytes());
        // 计算哈希并返回
        byte[] digest = messagedigest.digest();
        // 将摘要转换成16进制字符串
        return bufferToHex(digest);
    }
    

    愣着干嘛,用轮子呀

    话说我又要算字符串的 MD5 值,也要算文件的 MD5 值,而且转 16 进制字符串,这些我都要自己写?

    直接用轮子吧。

    常用的是这两个工具类:

    public void getMD5(String str) {
        // Spring的工具类
        org.springframework.util.DigestUtils.md5DigestAsHex(str.getBytes());
        // commons-codec包的工具类
        org.apache.commons.codec.digest.DigestUtils.md5Hex(str);
    }
    

    如果你不是 Spring 工程,且因为莫名其妙不能随便引用新的jar包,那么我建议直接把org.springframework.util.DigestUtils拷贝出来自己用就好了。不建议拷贝commons-codec包的工具类,因为额外引用的类太多。

    生成文件夹的 MD5 值

    现有的工具类没有直接计算文件夹 MD5 值的方法,而且本身文件夹也没法计算 MD5 值吧。

    但是一定要计算,那我们可以自己定义一个算法。很简单,如果是文件夹,则遍历文件夹下的全部文件,对每个文件都计算一次 MD5 值,放到一个列表里。最后把列表中的 MD5 值拼在一起生成一个新的 MD5 值作为文件夹的 MD5 值来使用就好了。

    代码如下(直接用了 Spring 的DigestUtils工具类):

    /**
     * 获取文件/文件夹md5信息
     * 文件夹md5生成逻辑:遍历文件夹下的全部文件,并计算文件的md5值。
     * 之后将所有文件的md5值拼接在一起去生成一个新的md5值作为文件夹的md5值。
     *
     * @param file
     * @return
     * @throws IOException
     * @throws NoSuchAlgorithmException
     */
    public String getFileMD5(File file) throws IOException {
        // 计算文件夹的md5值时,用于存放文件夹下每个文件的md5值
        Set md5List = new HashSet<>();
        fillMD5List(file, md5List);
        if (md5List.isEmpty()) {
            logger.info("路径不存在,不计算md5值,路径:" + file.getPath());
            return "";
        }
    
        if (md5List.size() == 1) {
            return new ArrayList<>(md5List).get(0);
        }
    
        StringBuilder sb = new StringBuilder();
        for (String s : md5List) {
            sb.append(s);
        }
        return DigestUtils.md5DigestAsHex(sb.toString().getBytes());
    }
    
    
    public void fillMD5List(File file, Set md5List) throws IOException {
        if (file == null || !file.exists()) {
            return;
        }
    
        if (file.isDirectory()) {
            File[] f = file.listFiles();
            if (f != null) {
                for (File value : f) {
                    fillMD5List(value, md5List);
                }
            }
        } else {
            String md5 = DigestUtils.md5DigestAsHex(new FileInputStream(file));
            md5List.add(md5);
        }
    }
    
  • 相关阅读:
    java/Android:将字符串按数量分割
    LeetCode每日一题——902. 最大为 N 的数字组合
    FPGA基础(数字电路)
    数据集笔记:Beijing-BRT-dataset
    【win 10】Chrome 添加YouTube™ 双字幕插件
    Git Rebase-提交整洁之道
    【算法|前缀和系列No.4】leetcode238. 除自身以外数组的乘积
    【HarmonyOS】【JAVA UI】HarmonyOS 如何集成KLog
    开源 RPA 和并行处理的力量
    HMS Core Discovery第16期回顾|与虎墩一起,玩转AI新“声”态
  • 原文地址:https://blog.csdn.net/u011291072/article/details/127107134