package com.itheima.util;

import java.security.MessageDigest;  // 导入MessageDigest类，用于进行MD5加密操作

/**
 * @program: Student_dorm_System
 * @description: MD5加密工具类
 * @author: Joyrocky
 * @create: 2019-04-13 13:04
 **/

public class MD5Util {

    // 将字节数组转换为16进制的字符串
    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();  // 用于存储转换后的字符串
        for (int i = 0; i < b.length; i++)  // 遍历字节数组
            resultSb.append(byteToHexString(b[i]));  // 将每个字节转换为16进制并添加到结果中

        return resultSb.toString();  // 返回转换后的16进制字符串
    }

    // 将单个字节转换为16进制的字符串表示
    private static String byteToHexString(byte b) {
        int n = b;  // 将byte类型转换为int类型，以便操作
        if (n < 0)  // 如果字节为负数，则调整为正数
            n += 256;  // 加256是为了将负值转换为正数
        int d1 = n / 16;  // 获取16进制的高位（十六进制的第一个数字）
        int d2 = n % 16;  // 获取16进制的低位（十六进制的第二个数字）
        return hexDigits[d1] + hexDigits[d2];  // 将高位和低位的16进制字符拼接成字符串返回
    }

    /**
     * 对输入字符串进行MD5加密
     *
     * @param origin       要加密的原始字符串
     * @param charsetname  字符集名称（如UTF-8）
     * @return             返回加密后的MD5大写字符串
     */
    private static String MD5Encode(String origin, String charsetname) {
        String resultString = null;  // 用于存储加密后的结果字符串
        try {
            resultString = new String(origin);  // 将原始字符串转换为新的字符串对象
            MessageDigest md = MessageDigest.getInstance("MD5");  // 获取MD5加密算法的MessageDigest实例
            if (charsetname == null || "".equals(charsetname))  // 如果字符集为空
                resultString = byteArrayToHexString(md.digest(resultString.getBytes()));  // 使用默认字符集进行加密
            else
                resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));  // 使用指定字符集进行加密
        } catch (Exception exception) {
            // 异常捕获部分，这里没有处理异常，可以在实际使用时添加日志或者其他处理方式
        }
        return resultString.toUpperCase();  // 返回加密后的MD5字符串并转换为大写
    }

    /**
     * 对输入字符串进行MD5加密（使用UTF-8字符集）
     *
     * @param origin 要加密的原始字符串
     * @return       返回加密后的MD5大写字符串
     */
    public static String MD5EncodeUtf8(String origin) {
        // 盐值Salt加密：可以在此处为原始字符串添加盐值增强安全性，具体的盐值配置可以在Properties文件中配置
        // origin = origin + PropertiesUtil.getProperty("password.salt", "");
        return MD5Encode(origin, "utf-8");  // 调用MD5Encode方法，使用UTF-8字符集进行加密
    }

    // 定义16进制的字符数组，用于字节到16进制的转换
    private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

}
