签名字符串生成 参数名ASCII码从小到大排序

背景:

网上签名大部分用的到了阿里的fastjon,奈何有些项目不能使用这个jar包,只能另寻方法

签名规则说明:

签名生成的通用步骤如下:

第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。

特别注意以下重要规则:

    ◆ 参数名ASCII码从小到大排序(字典序);
    ◆ 如果参数的值为空不参与签名;
    ◆ 参数名区分大小写;
    ◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
    ◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段

第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。

编码:

很多接口文档都是安装这个来签名,以下方法为生成复杂字符串的编码。原始字符串为:

{"code":1000,"msg":"成功","sign":"1c87a66dc889f660b4d6f689da44fbc5f5a4cbfa1616a62829b9518f74a12e27","data":{"taskId":94,"taskVersion":1605859691729,"sessionId":"1630582279605eh3qPMCG","isDelete":0,"diagnosisEndTime":1633108878,"taskInfo":{"taskType":1,"diagnoseType":1,"diagnoseConfig":{"executeNumber":0},"otxInfo":[{"id":118,"strategyId":94,"otxId":39,"otxFileName":"fileName.ttb","ttbFileName":"fileName.ttb","ttbFilePath":"filePath","diagnosisFun":"测试功能2"},{"id":119,"strategyId":94,"otxId":38,"otxFileName":"fileName.ttb","ttbFileName":"fileName.ttb","ttbFilePath":"filePath","diagnosisFun":"测试功能"}]}}}

字符串转Map:

使用的是gson,也可以替换成jackson

Gson gson = new Gson();
Map<String, Object> map = new HashMap<String, Object>();
Map<String, Object> tmpMap = gson.fromJson(jsonStr, map.getClass());

map转Sting字符串:

public static String getSignContent(Map<String, Object> params) {
        List<String> keys = new ArrayList<String>(params.keySet());
        Map<String, String> datas = new HashMap<>(16);
        params.remove("sign");
        buildMapData("", params, datas);
        Set<String> strings = datas.keySet();
        List<String> keyList = new ArrayList<>(strings);
        Collections.sort(keyList);
        StringBuffer sb = new StringBuffer();
        for (String key : keyList) {
            sb.append("&");
            sb.append(key.replaceFirst(".", ""));
            sb.append("=");
            sb.append(datas.get(key));
        }
        String content = sb.toString().replaceFirst("&", "");
        return content;
    }

排序方法:

public static void buildMapData(String prefix, Object object, Map<String, String> datas) {
        if (object instanceof List) {
            List arrayList = (List) object;
            for (int k = 0; k < arrayList.size(); k++) {
                String pre = prefix.replaceFirst(".", "");
                pre = prefix + "[" + k + "]";
                Map<String, Object> map = (Map<String, Object>) arrayList.get(k);
                Set<String> keySet = map.keySet();
                List<String> result = new ArrayList<>(keySet);
                for (String mapKey : result) {
                    Object value = map.get(mapKey);
                    String key = pre + "." + mapKey;
                    buildMapData(key, value, datas);
                }
            }
        } else if (object instanceof Map) {
            Map linkedHashMap = (Map) object;
            Set<String> keySet = linkedHashMap.keySet();
            List<String> result = new ArrayList<>(keySet);
            for (String mapKey : result) {
                Object value = linkedHashMap.get(mapKey);
                String pre = prefix + "." + mapKey;
                buildMapData(pre, value, datas);
            }
        } else {
            datas.put(prefix, object.toString());
        }
    }

结果:

用这个方法生成的签名串:

code=1000.0&data.diagnosisEndTime=1.633108878E9&data.isDelete=0.0&data.sessionId=1630582279605eh3qPMCG&data.taskId=94.0&data.taskInfo.diagnoseConfig.executeNumber=0.0&data.taskInfo.diagnoseType=1.0&data.taskInfo.otxInfo[0].diagnosisFun=测试功能2&data.taskInfo.otxInfo[0].id=118.0&data.taskInfo.otxInfo[0].otxFileName=fileName.ttb&data.taskInfo.otxInfo[0].otxId=39.0&data.taskInfo.otxInfo[0].strategyId=94.0&data.taskInfo.otxInfo[0].ttbFileName=fileName.ttb&data.taskInfo.otxInfo[0].ttbFilePath=filePath&data.taskInfo.otxInfo[1].diagnosisFun=测试功能&data.taskInfo.otxInfo[1].id=119.0&data.taskInfo.otxInfo[1].otxFileName=fileName.ttb&data.taskInfo.otxInfo[1].otxId=38.0&data.taskInfo.otxInfo[1].strategyId=94.0&data.taskInfo.otxInfo[1].ttbFileName=fileName.ttb&data.taskInfo.otxInfo[1].ttbFilePath=filePath&data.taskInfo.taskType=1.0&data.taskVersion=1.605859691729E12&msg=成功

结束:

这个方法基本满足所有的场景,支持各种嵌套模式!

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值