package com.hfkj.common.utils; import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.util.Map; import java.util.TreeMap; public class PetroEncryptUtil { /** * 生成签名 * * @param signMaps * @return * @throws Exception */ public static String generateSign(Map signMaps) { StringBuilder sb = new StringBuilder(); TreeMap sortedMap = new TreeMap<>(signMaps); // 字典序 for (Map.Entry entry : sortedMap.entrySet()) { String key = entry.getKey(); String value = (String) entry.getValue(); // 为空不参与签名、参数名区分大小写 if (!"sign".equals(key)) { sb.append(key).append("=").append(value).append("&"); } } sb = new StringBuilder(sb.substring(0, sb.length() - 1)); // MD5加密 return md532(sb.toString()); } /*** * MD5加码 生成32位md5码 */ public static String md532(String inStr) { MessageDigest md5; try { md5 = MessageDigest.getInstance("MD5"); } catch (Exception e) { System.out.println(e); e.printStackTrace(); return ""; } char[] charArray = inStr.toCharArray(); byte[] byteArray = new byte[charArray.length]; for (int i = 0; i < charArray.length; i++) byteArray[i] = (byte) charArray[i]; byte[] md5Bytes = md5.digest(byteArray); StringBuilder hexValue = new StringBuilder(); for (byte md5Byte : md5Bytes) { int val = ((int) md5Byte) & 0xff; if (val < 16) hexValue.append("0"); hexValue.append(Integer.toHexString(val)); } return hexValue.toString(); } /** * 加密解密算法 * * @param inStr 加密字符串 * @param secretKey 秘钥 * 算法: * 1:加密字符串和秘钥转换成字符数组; * 2:秘钥去重复 * 3:循环一(秘钥字符串数组){ 循环二(加密字符串数组){ * 秘钥字符的ASC码 与 加密字符的ASC码 进行二进制异或运算 * } * } * 4:把字符串转为16进制 */ private static String convert(String inStr, String secretKey) { char[] a = inStr.toCharArray(); char[] s = rmRepeated(secretKey).toCharArray(); for (int i = 0; i < s.length; i++) { for (int j = 0; j < a.length; j++) { a[j] = (char) (a[j] ^ s[i]); } } return new String(a); } /** * 清除字符串中重复字母算法 * * @param s * @return */ private static String rmRepeated(String s) { int len = s.length(); int k = 0; int count = 0; String str = ""; char[] c = new char[len]; for (int i = 0; i < len; i++) { c[i] = s.charAt(i); } for (int i = 0; i < len; i++) { k = i + 1; while (k < len - count) { if (c[i] == c[k]) { for (int j = k; j < len - 1; j++) { c[j] = c[j + 1];// 出现重复字母,从k位置开始将数组往前挪位 } count++;// 重复字母出现的次数 k--; } k++; } } for (int i = 0; i < len - count; i++) { str += String.valueOf(c[i]); } return str; } /* * 将字符串编码成16进制数字,适用于所有字符(包括中文) */ private static String hexString = "0123456789ABCDEF"; public static String encode(String str) { // 根据默认编码获取字节数组 String r; byte[] bytes = str.getBytes(StandardCharsets.UTF_8); StringBuilder sb = new StringBuilder(bytes.length * 2); // 将字节数组中每个字节拆解成2位16进制整数 for (byte aByte : bytes) { sb.append(hexString.charAt((aByte & 0xf0) >> 4)); sb.append(hexString.charAt((aByte & 0x0f))); } r = sb.toString(); return r; } /* * 将16进制数字解码成字符串,适用于所有字符(包括中文) */ public static String decode(String bytes) { String r = ""; try { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(bytes.length() / 2); // 将每2位16进制整数组装成一个字节 for (int i = 0; i < bytes.length(); i += 2) { byteArrayOutputStream.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString.indexOf(bytes.charAt(i + 1)))); } r = byteArrayOutputStream.toString("UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return r; } /** * 加密 * * @param inStr 原字符串 * @param secretKey 秘钥 * @return */ public static String encrypt(String inStr, String secretKey) { String hexStr = convert(inStr, secretKey); return encode(hexStr); } /** * 解密 * * @param inStr 原字符串 * @param secretKey 秘钥 * @return */ public static String decrypt(String inStr, String secretKey) { String hexStr = decode(inStr); return convert(hexStr, secretKey); } }