业务需求:
需要调用XXX接口。
官网文档要求如下:
Sign算法说明
举例:假设请求参数键值对如下
appkey : test2-xx page_no : 0 end_time : 2016-08-01 13:00:00 start_time : 2016-08-01 12:00:00 page_size : 40 sid : test2 timestamp : 1470042310 |
- 第一步 对数所有请求参数按照键名进行正序排序,排序结果如下,注意要保持键值对的对应关系且appsecret不参与运算。
appkey : test2-xx end_time : 2016-08-01 13:00:00 page_no : 0 page_size : 40 sid : test2 start_time : 2016-08-01 12:00:00 timestamp : 1470042310 |
- 第二步 循环对每个键值进行处理:
1.处理 appkey
1.1 appkey 采用utf8编码格式的字符长度并保留两位,不够的位数补0,计算结果为:06
1.2 将1.1计算的长度 06 和 appkey 用 - 作为分隔符进行拼接,拼接结果为 06-appkey
1.3 test2-xx 采用utf8编码格式的字符长度不足四位,保留四位,不够的位数补0,计算结果为:0008,如果超过4位,保留实际结果,如:10000
1.4 将1.3计算的长度 0008 和 test2-xx 用 - 作为分隔符进行拼接,拼接结果为 0008-test2-xx
1.5 将1.2 和 1.4 的拼接结果用 : 进行拼接 ,拼接结果为 06-appkey:0008-test2-xx
1.6 将1.5的结果最后拼接上分号 ; 拼接结果为 06-appkey:0008-test2-xx;
2.处理 end_time 同1处理
3.处理 page_no 同1处理
4.处理 page_size 同1处理
5.处理 sid 同1处理
6.处理 start_time 同1处理
7.处理 timestamp 注意前五步和1处理方法相同,因为 timestamp 是最后一个请求参数,所以不需要 1.6步骤
最后的处理结果为:
06-appkey:0008-test2-xx;08-end_time:0019-2016-08-01 13:00:00;07-page_no:0001-0;09-page_size:0002-40;03-sid:0005-test2;10-start_time:0019-2016-08-01 12:00:00;09-timestamp:0010-1470042310
注意:示例中的参数为查询类接口请求参数,创建类接口中的参数包含json串,比如:创建原始订单:trade_list = [] 这里是订单的json数据,json串当作正常的字符串进行处理 |
- 第三步 计算sign
1.获取appsecret 假如当前实例中的 appsecret 为 12345
2.将appsecret拼接在第二步的结果后面,注意没有任何拼接符,结果如下:06-appkey:0008-test2-xx;08-end_time:0019-2016-08-01 13:00:00;07-page_no:0001-0;09-page_size:0002-40;03-sid:0005-test2;10-start_time:0019-2016-08-01 12:00:00;09-timestamp:0010-147004231012345
3.将上述字符串进行md5加密后即可得到sign,要求MD5方法返回的是32位小写的MD5值,计算结果如下: ad4e6fe037ea6e3ba4768317be9d1309
4.将计算的sign作为一个请求参数放到参数列表中 sid : test2 appkey : test2-xx timestamp : 1470042310 start_time : 2016-08-01 12:00:00 end_time : 2016-08-01 13:00:00 page_no : 0 page_size : 40 sign : ad4e6fe037ea6e3ba4768317be9d1309 |
源码:
public class signTest {
public static String getSignToken(Map<String, Object> params) {
String appsecret = "12345";
List<String> keys = new ArrayList<String>(params.keySet());
String finalStr="";
//第一步 正序排序
Collections.sort(keys);
//第二步 循环对每个键值进行处理
String prestr = "";
for (int i = 0; i < keys.size(); i++) {
//组装key 长度
Integer keyNum=keys.get(i).length();
String key="";
if(keyNum<10){
key=String.format("%2d", keyNum).replace(" ", "0");
}else if(keyNum>=10){
key=keyNum.toString();
}
prestr=prestr+key;
//组装key 值
prestr=prestr+"-"+keys.get(i)+":";
//组装value 长度
String value="";
Object obt=params.get(keys.get(i));
String valueStr=obt.toString();
Integer valueNum=valueStr.length();
if(valueNum<10000){
value=String.format("%4d", valueNum).replace(" ", "0");
}else{
value=valueStr;
}
prestr=prestr+value;
//组装value 值
prestr=prestr+"-"+valueStr+";";
}
if(prestr.length()>0){
prestr=prestr.substring(0,prestr.length()-1);
}
//第三步 计算sign md5加密后,返回的是32位小写的MD5值
finalStr=prestr+appsecret;
System.out.println("finalStr==="+finalStr);
String md5=md5Digest(finalStr);
return md5;
}
//md5加密后,返回的是32位小写的MD5值
public static String md5Digest(String paramString) {
MessageDigest localMessageDigest;
StringBuilder localStringBuilder = new StringBuilder();
byte[] arrayOfByte = null;
try {
localMessageDigest = MessageDigest.getInstance("MD5");
arrayOfByte = localMessageDigest.digest(paramString.getBytes("utf-8"));
int j = arrayOfByte.length;
for (int i = 0; i < j; i++) {
String k = Integer.toHexString(arrayOfByte[i] & 0xFF);
if (k.length() == 1) {
localStringBuilder.append("0");
}
localStringBuilder.append(k);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return localStringBuilder.toString();
}
public static void main(String[] args) {
Map<String, Object> params=new HashMap<String, Object>();
params.put("appkey", "test2-xx");
params.put("page_no", "0");
params.put("end_time", "2016-08-01 13:00:00");
params.put("start_time", "2016-08-01 12:00:00");
params.put("page_size", "40");
params.put("sid", "test2");
params.put("timestamp", "1470042310");
String aa=getSignToken(params);
System.out.println("result=="+aa);
}
}
技术点:
md5加密后,返回的是32位小写的MD5值:
https://blog.csdn.net/yanqiqi777/article/details/88422418
java不足位数补0:
https://blog.csdn.net/yangguangniubi/article/details/90199663