From 8c4e48f0ef3da7e60bcf7f7a49bda633f873e336 Mon Sep 17 00:00:00 2001 From: wsy182 <2392948297@qq.com> Date: Mon, 24 Nov 2025 11:12:25 +0800 Subject: [PATCH] =?UTF-8?q?feat(utils):=20=E6=B7=BB=E5=8A=A0MD5=E7=AD=BE?= =?UTF-8?q?=E5=90=8D=E7=94=9F=E6=88=90=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现了基于Java规则的MD5签名计算方法 - 支持参数映射排序与URL编码处理 - 添加了空格去除和特殊字符处理逻辑 - 集成了时间戳、随机字符串生成功能 - 提供完整的curl请求示例输出 - 支持复杂对象序列化为JSON请求体 - 实现了多层级参数拼接与签名验证 --- generateSign.py | 97 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 generateSign.py diff --git a/generateSign.py b/generateSign.py new file mode 100644 index 0000000..7f71b5c --- /dev/null +++ b/generateSign.py @@ -0,0 +1,97 @@ +import json +import time +import uuid +import urllib.parse +import hashlib + + +# =================== MD5签名计算 =================== +def calculate_md5(param, secret_key): + # Java 规则:MD5(secretKey + param) + return hashlib.md5((secret_key + param).encode('utf-8')).hexdigest() + + +def create_sign(param_map, secret_key): + sorted_keys = sorted(param_map.keys()) + parts = [] + + for key in sorted_keys: + val = param_map[key] + + if val is None: + parts.append(f"{key}=") + continue + + if isinstance(val, list): + for item in val: + encoded_val = urllib.parse.quote(str(item), encoding='utf-8') + parts.append(f"{key}={encoded_val}") + continue + + val_str = str(val) + + if key != "REQUEST_BODY_CONTENT": + val_str = urllib.parse.quote(val_str, encoding='utf-8') + + parts.append(f"{key}={val_str}") + + param = "&".join(parts) + + # Java逻辑: .replaceAll("\\s", "") + param = "".join(param.split()) + + print("参数明文 param:", param) + + sign = calculate_md5(param, secret_key) + print("生成签名 sign:", sign) + + return sign + + +# =================== Python 主程序 =================== +if __name__ == '__main__': + platform_ifc_system_code = "9f5bbb73710c4a6a8923c278ffa00d50" + + systemCode = "57395d2bc668496c9c57d8f2b19bd516" + + appId = "57395d2bc668496c9c57d8f2b19bd516" + secret_key = "lC4&NvBQcnvgH@i+io=k#K3HO5aCiuHD" + + ts = str(int(time.time() * 1000)) + randomString = uuid.uuid4().hex + + selector = { + "searchKeys": ["b353614a47e2425a8a8885d270267407", "3DC1B33E1B5B431E99FA163BF9E86E6A", "9cb864213c6f48ceaf90e98e7ca375e9"], + "userType": "0", + "hasCascade": True + } + + request_body_json = json.dumps(selector, separators=(',', ':')) + + param_map = { + "systemCode": systemCode, + "timestamp": ts, + "nonce": randomString, + "REQUEST_BODY_CONTENT": request_body_json + } + + sign = create_sign(param_map, secret_key) + + ifcUrl = "https://dpc.cet.cnooc/prod-api/cenertech-interface-center/IFC2" + apiPath = "/userListByDeptSearch" + + fullUrl = f"{ifcUrl}/{platform_ifc_system_code}{apiPath}" + + curl = f""" +curl -X POST "{fullUrl}" \\ + -H "Content-Type: application/json" \\ + -H "systemCode: {systemCode}" \\ + -H "timestamp: {ts}" \\ + -H "nonce: {randomString}" \\ + -H "sign: {sign}" \\ + -H "App-Id: {appId}" \\ + -d '{request_body_json}' +""" + + print("\n===== 最终 curl 请求 =====\n") + print(curl)