package com.ruoyi.common.utils.civilAviation; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.MessageDigest; import java.util.*; import org.apache.commons.lang3.StringUtils; public class ServiceOrderSign { private static final int BITS_TO_A_BYTE = 8; private static final int BYTES_TO_A_WORD = 4; private static final int BITS_TO_A_WORD = 32; private static final long[] m_lOnBits = new long[31]; private static final long[] m_l2Power = new long[31]; static { // 初始化位操作数组 m_lOnBits[0] = 1L; m_lOnBits[1] = 3L; m_lOnBits[2] = 7L; m_lOnBits[3] = 15L; m_lOnBits[4] = 31L; m_lOnBits[5] = 63L; m_lOnBits[6] = 127L; m_lOnBits[7] = 255L; m_lOnBits[8] = 511L; m_lOnBits[9] = 1023L; m_lOnBits[10] = 2047L; m_lOnBits[11] = 4095L; m_lOnBits[12] = 8191L; m_lOnBits[13] = 16383L; m_lOnBits[14] = 32767L; m_lOnBits[15] = 65535L; m_lOnBits[16] = 131071L; m_lOnBits[17] = 262143L; m_lOnBits[18] = 524287L; m_lOnBits[19] = 1048575L; m_lOnBits[20] = 2097151L; m_lOnBits[21] = 4194303L; m_lOnBits[22] = 8388607L; m_lOnBits[23] = 16777215L; m_lOnBits[24] = 33554431L; m_lOnBits[25] = 67108863L; m_lOnBits[26] = 134217727L; m_lOnBits[27] = 268435455L; m_lOnBits[28] = 536870911L; m_lOnBits[29] = 1073741823L; m_lOnBits[30] = 2147483647L; m_l2Power[0] = 1L; m_l2Power[1] = 2L; m_l2Power[2] = 4L; m_l2Power[3] = 8L; m_l2Power[4] = 16L; m_l2Power[5] = 32L; m_l2Power[6] = 64L; m_l2Power[7] = 128L; m_l2Power[8] = 256L; m_l2Power[9] = 512L; m_l2Power[10] = 1024L; m_l2Power[11] = 2048L; m_l2Power[12] = 4096L; m_l2Power[13] = 8192L; m_l2Power[14] = 16384L; m_l2Power[15] = 32768L; m_l2Power[16] = 65536L; m_l2Power[17] = 131072L; m_l2Power[18] = 262144L; m_l2Power[19] = 524288L; m_l2Power[20] = 1048576L; m_l2Power[21] = 2097152L; m_l2Power[22] = 4194304L; m_l2Power[23] = 8388608L; m_l2Power[24] = 16777216L; m_l2Power[25] = 33554432L; m_l2Power[26] = 67108864L; m_l2Power[27] = 134217728L; m_l2Power[28] = 268435456L; m_l2Power[29] = 536870912L; m_l2Power[30] = 1073741824L; } private static long LShift(long lValue, int iShiftBits) { if (iShiftBits == 0) { return lValue; } else if (iShiftBits == 31) { return (lValue & 1) != 0 ? 0x80000000L : 0; } else if (iShiftBits < 0 || iShiftBits > 31) { throw new RuntimeException("Invalid shift bits"); } return ((lValue & m_lOnBits[31 - iShiftBits]) << iShiftBits); } private static long RShift(long lValue, int iShiftBits) { if (iShiftBits == 0) { return lValue; } else if (iShiftBits == 31) { return (lValue & 0x80000000L) != 0 ? 1 : 0; } else if (iShiftBits < 0 || iShiftBits > 31) { throw new RuntimeException("Invalid shift bits"); } return (lValue >>> iShiftBits) & (0x7FFFFFFFL >>> (iShiftBits - 1)); } private static long RotateLeft(long lValue, int iShiftBits) { return (LShift(lValue, iShiftBits) | RShift(lValue, 32 - iShiftBits)) & 0xFFFFFFFFL; } private static long AddUnsigned(long lX, long lY) { long lX8 = lX & 0x80000000L; long lY8 = lY & 0x80000000L; long lX4 = lX & 0x40000000L; long lY4 = lY & 0x40000000L; long lResult = (lX & 0x3FFFFFFFL) + (lY & 0x3FFFFFFFL); if ((lX4 & lY4) != 0) { lResult = lResult ^ 0x80000000L ^ lX8 ^ lY8; } else if ((lX4 | lY4) != 0) { if ((lResult & 0x40000000L) != 0) { lResult = lResult ^ 0xC0000000L ^ lX8 ^ lY8; } else { lResult = lResult ^ 0x40000000L ^ lX8 ^ lY8; } } else { lResult = lResult ^ lX8 ^ lY8; } return lResult; } private static long F(long x, long y, long z) { return (x & y) | (~x & z); } private static long G(long x, long y, long z) { return (x & z) | (y & ~z); } private static long H(long x, long y, long z) { return x ^ y ^ z; } private static long I(long x, long y, long z) { return y ^ (x | ~z); } private static void FF(long[] a, long b, long c, long d, long x, int s, long ac) { a[0] = AddUnsigned(a[0], AddUnsigned(AddUnsigned(F(b, c, d), x), ac)); a[0] = RotateLeft(a[0], s); a[0] = AddUnsigned(a[0], b); } private static void GG(long[] a, long b, long c, long d, long x, int s, long ac) { a[0] = AddUnsigned(a[0], AddUnsigned(AddUnsigned(G(b, c, d), x), ac)); a[0] = RotateLeft(a[0], s); a[0] = AddUnsigned(a[0], b); } private static void HH(long[] a, long b, long c, long d, long x, int s, long ac) { a[0] = AddUnsigned(a[0], AddUnsigned(AddUnsigned(H(b, c, d), x), ac)); a[0] = RotateLeft(a[0], s); a[0] = AddUnsigned(a[0], b); } private static void II(long[] a, long b, long c, long d, long x, int s, long ac) { a[0] = AddUnsigned(a[0], AddUnsigned(AddUnsigned(I(b, c, d), x), ac)); a[0] = RotateLeft(a[0], s); a[0] = AddUnsigned(a[0], b); } private static long[] ConvertToWordArray(byte[] messageBytes) { int lMessageLength = messageBytes.length; int lNumberOfWords = (((lMessageLength + 8) >> 6) + 1) << 4; long[] lWordArray = new long[lNumberOfWords]; int lBytePosition = 0; for (int lWordCount = 0; lBytePosition < lMessageLength; lWordCount++, lBytePosition += 4) { lWordArray[lWordCount] = 0; for (int lByteCount = 0; lByteCount < Math.min(4, lMessageLength - lBytePosition); lByteCount++) { lWordArray[lWordCount] |= ((messageBytes[lBytePosition + lByteCount] & 0xFF) << (lByteCount << 3)); } } // 标记结束 lWordArray[lBytePosition >> 2] |= 0x80 << ((lBytePosition % 4) << 3); // 设置消息长度 lWordArray[lNumberOfWords - 2] = (lMessageLength << 3) & 0xFFFFFFFFL; lWordArray[lNumberOfWords - 1] = (lMessageLength >>> 29) & 0xFFFFFFFFL; return lWordArray; } private static String WordToHex(long lValue) { StringBuilder wordToHex = new StringBuilder(); for (int lCount = 0; lCount <= 3; lCount++) { long lByte = (lValue >>> (lCount << 3)) & 255; String byteHex = Integer.toHexString((int) lByte); if (byteHex.length() == 1) { wordToHex.append("0"); } wordToHex.append(byteHex); } return wordToHex.toString(); } public static String MD5(String message, String charset) { try { byte[] messageBytes; if ("utf-8".equalsIgnoreCase(charset)) { messageBytes = message.getBytes("UTF-8"); } else { messageBytes = message.getBytes(); } long[] x = ConvertToWordArray(messageBytes); // 初始化变量 long a = 0x67452301L; long b = 0xEFCDAB89L; long c = 0x98BADCFEL; long d = 0x10325476L; // 常量定义 final int S11 = 7; final int S12 = 12; final int S13 = 17; final int S14 = 22; final int S21 = 5; final int S22 = 9; final int S23 = 14; final int S24 = 20; final int S31 = 4; final int S32 = 11; final int S33 = 16; final int S34 = 23; final int S41 = 6; final int S42 = 10; final int S43 = 15; final int S44 = 21; // 主循环 for (int k = 0; k < x.length; k += 16) { long AA = a; long BB = b; long CC = c; long DD = d; long[] aArray = {a}; long[] dArray = {d}; long[] cArray = {c}; long[] bArray = {b}; // Round 1 FF(aArray, b, c, d, x[k + 0], S11, 0xD76AA478L); a = aArray[0]; FF(dArray, a, b, c, x[k + 1], S12, 0xE8C7B756L); d = dArray[0]; FF(cArray, d, a, b, x[k + 2], S13, 0x242070DBL); c = cArray[0]; FF(bArray, c, d, a, x[k + 3], S14, 0xC1BDCEEEL); b = bArray[0]; // ... 继续实现所有轮次 a = AddUnsigned(a, AA); b = AddUnsigned(b, BB); c = AddUnsigned(c, CC); d = AddUnsigned(d, DD); } return (WordToHex(a) + WordToHex(b) + WordToHex(c) + WordToHex(d)).toLowerCase(); } catch (Exception e) { throw new RuntimeException("MD5 calculation error", e); } } /** * 生成签名 * @param params 请求参数集合 * @return 签名值 */ public static String generateSign(Map params,String APP_SECRET) { // 1. 移除sign参数 params.remove("sign"); params.remove("Sign"); // 2. 按ASCII码排序(字典序) List keys = new ArrayList<>(params.keySet()); Collections.sort(keys); // 3. 拼接字符串 (Key1Value1Key2Value2...) StringBuilder stringA = new StringBuilder(); for (String key : keys) { String value = params.get(key); if (value != null && !value.isEmpty()) { // 将参数名首字母大写 // String capitalizedKey = StringUtils.capitalize(key); stringA.append(key).append(value); } } // 4. 拼接APP_SECRET String stringSignTemp = stringA.toString() + APP_SECRET; // 5. MD5运算并转小写 try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] bytes = stringSignTemp.getBytes("UTF-8"); md.update(bytes); byte[] md5Bytes = md.digest(); StringBuilder hexValue = new StringBuilder(); for (byte b : md5Bytes) { int val = ((int) b) & 0xff; if (val < 16) { hexValue.append("0"); } hexValue.append(Integer.toHexString(val)); } return hexValue.toString().toLowerCase(); } catch (Exception e) { throw new RuntimeException("MD5加密出错", e); } } /** * 验证签名 * @param params 请求参数集合 * @param sign 签名值 * @return 验证结果 */ public static boolean verifySign(Map params, String sign) { // String generatedSign = generateSign(params); // return generatedSign.equalsIgnoreCase(sign); return false; } /** * 使用示例 */ public static void main(String[] args) { // 测试用例 // Map params = new HashMap<>(); // params.put("method", "User_Login"); // params.put("LoginType", "0"); // params.put("UserID", "10"); // // String sign = generateSign(params); // System.out.println("生成的签名: " + sign); // 应输出: 9a0a8659f005d6984697e2ca0a9cf3b7 } }