package com.sckw.access.util; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * MD5 消息摘要算法(利用哈希算法来加密的) * * @author xcq * @date 2022年07月27日 20:04 */ @Slf4j public class MD5Util { //十六进制下数字到字符的映射数组 private final static String[] HEX_DIGITS = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; /** * md5加密算法 返回String * * @param originString * @return */ public static String encodeByMD5(String originString) { if (originString != null) { try { //创建具有指定算法名称的信息摘要 MessageDigest md = MessageDigest.getInstance("MD5"); //使用指定的字节数组对摘要进行最后更新,然后完成摘要计算 byte[] results = md.digest(originString.getBytes()); //将得到的字节数组变成字符串返回 StringBuilder sb = new StringBuilder(); for (int j : results) { int n = j; if (n < 0) { n = 256 + n; } int d1 = n / 16; int d2 = n % 16; sb.append(HEX_DIGITS[d1]).append(HEX_DIGITS[d2]); } return sb.toString(); } catch (Exception ex) { ex.printStackTrace(); } } return null; } /** * 计算字符串的MD5值 * * @param string 明文 * @return 字符串的MD5值 */ public static String md5(String string) { if (string.isEmpty()) { return ""; } MessageDigest md5; try { md5 = MessageDigest.getInstance("MD5"); byte[] bytes = md5.digest(string.getBytes(StandardCharsets.UTF_8)); StringBuilder result = new StringBuilder(); for (byte b : bytes) { /* & 0xff 可以将负数转为正数*/ String temp = Integer.toHexString(b & 0xff); // 16进制数 temp小于16 if (temp.length() == 1) { temp = "0" + temp; } result.append(temp); } return result.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } /*其它方法*/ /** * md5摘要 * * @param s 需要转换的字符串 * @return 返回字节形式的md5摘要数据 */ public static byte[] byteMD5(String s) { MessageDigest md; try { md = MessageDigest.getInstance("MD5"); md.reset(); md.update(s.getBytes(StandardCharsets.UTF_8)); return md.digest(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 将字节数据转换为16进制的字符串数据 * * @param hash 转换后的字节数组 * @return 返回16进制的字符串 */ public static String byteToHex(byte[] hash) { if (hash == null) { return null; } StringBuffer buf = new StringBuffer(hash.length * 2); int i; for (i = 0; i < hash.length; i++) { /* & 0xff 可以将负数转为正数*/ /* <0x10 表示小于16,需要进行补零*/ if ((hash[i] & 0xff) < 0x10) { buf.append("0"); } buf.append(Long.toString(hash[i] & 0xff, 16)); } return buf.toString(); } /** * 将字节数组转换为十六进制字符串 * * @param data 待转换的字节数组 * @return 转换后的十六进制字符串 */ private static String toHexString(byte[] data) { StringBuilder sb = new StringBuilder(); for (byte b : data) { sb.append(String.format("%02X", b)); } return sb.toString(); } /** * 验证MD5校验值是否正确 * * @param data 待验证的数据 * @param md5ToCheck 待验证的MD5校验值 * @return true表示校验通过,false表示校验失败 */ public static boolean verifyMD5(String data, String md5ToCheck) { String check = md5(data); log.info("我方签名:{}", check); log.info("来访者签名:{}", md5ToCheck); return StringUtils.equals(check, md5ToCheck); } }