liusuyi
2026-05-18 b5cd784d0cde5b7c82ea78aef4ac0e5a161d8c5d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package com.ard.work.sdk.zlxd.utils;
 
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
 
/**
 * MD5加密工具类
 * 支持普通MD5、带盐值MD5、16位/32位加密结果
 */
public class MD5Utils {
 
    /**
     * 私有构造器,禁止实例化
     */
    private MD5Utils() {
    }
 
    /**
     * 基础MD5加密(32位小写)
     * @param content 要加密的内容
     * @return 32位小写MD5加密结果
     */
    public static String md5(String content) {
        return md5(content, null, StandardCharsets.UTF_8, false);
    }
 
    /**
     * 带盐值的MD5加密(32位小写)
     * @param content 要加密的内容
     * @param salt 盐值(推荐使用随机字符串,避免彩虹表破解)
     * @return 带盐值的32位小写MD5加密结果
     */
    public static String md5WithSalt(String content, String salt) {
        if (salt == null || salt.isEmpty()) {
            return md5(content);
        }
        // 盐值拼接规则:内容 + 盐值(也可根据需求调整为 盐值 + 内容 + 盐值)
        return md5(content + salt, null, StandardCharsets.UTF_8, false);
    }
 
    /**
     * 通用MD5加密方法(支持自定义编码、是否16位结果)
     * @param content 加密内容
     * @param salt 盐值(可为null)
     * @param charset 字符编码
     * @param is16Bit 是否返回16位结果(默认32位)
     * @return MD5加密结果
     */
    public static String md5(String content, String salt, java.nio.charset.Charset charset, boolean is16Bit) {
        if (content == null) {
            throw new IllegalArgumentException("加密内容不能为空");
        }
        try {
            // 初始化MD5摘要算法
            MessageDigest md = MessageDigest.getInstance("MD5");
            
            // 拼接盐值(如果有)
            String encryptContent = content;
            if (salt != null && !salt.isEmpty()) {
                encryptContent += salt;
            }
            
            // 计算MD5摘要
            byte[] digest = md.digest(encryptContent.getBytes(charset));
            
            // 将字节数组转换为16进制字符串
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                // 转换为两位16进制数,不足补0
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    sb.append('0');
                }
                sb.append(hex);
            }
            
            // 16位结果:截取32位结果的第8到24位
            if (is16Bit) {
                return sb.substring(8, 24);
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            // MD5是JDK内置算法,理论上不会抛出该异常
            throw new RuntimeException("MD5加密算法不存在", e);
        }
    }
 
    // 测试示例
    public static void main(String[] args) {
        // 测试普通MD5加密
        String plainText = "SDtt@0531";
        String md5Result = MD5Utils.md5(plainText);
        System.out.println("普通MD5加密(32位):" + md5Result); // 输出:e10adc3949ba59abbe56e057f20f883e
 
        // 测试带盐值MD5加密
        String salt = "8738783d7abd9960ec26b26d0dc1ebc5"; // 自定义盐值
        String md5WithSaltResult = MD5Utils.md5WithSalt(plainText, salt);
        System.out.println("带盐值MD5加密:" + md5WithSaltResult); // 输出:3f79bb7b435b05321651daefd374cdc6
 
        // 测试16位MD5加密
        String md516BitResult = MD5Utils.md5(plainText, null, StandardCharsets.UTF_8, true);
        System.out.println("16位MD5加密:" + md516BitResult); // 输出:49ba59abbe56e057
    }
}