公告:1.恭喜本站微信硬件蓝牙教程阅读总数突破100万次,微信jsapi阅读总数突破10万次... 2.友情交换/给本站留言

案例归档:  java 对数组里的每一个值从a到z的顺序排序,若遇到相同首字母,则看第二个字母,以此类推—实现代码

生成待签名字符串

对于如下的参数数组:

string[] parameters={
    "attachedData={merBillNo:2015090700000000}",
    "merOrderId=2015090700000000",
    "targetOrderId=2015090700000000",
    "buyerUsername=张三",
    "status=SUCCESS",
    "invoiceAmount=800",
    "totalAmount=1000",
    "billFunds=COUPON:200|PCARD:800",
    "billFundsDesc=优惠金额2.00元,银行卡支付金额8.00元",
    "payTime=2015-09-07 16:00:00"
};

对数组里的每一个值从a到z的顺序排序,若遇到相同首字母,则看第二个字母,以此类推。

排序完成之后,再把所有数组值以“&”字符连接起来.

import java.security.MessageDigest;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

public class SignUtil {
	/**
     * 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。V型知识库www.vxzsk.com
     */
    public String createSign(SortedMap<String, String> packageParams) throws Exception {
        StringBuffer sb = new StringBuffer();
        Set<?> es = packageParams.entrySet();
        Iterator<?> it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
        String sign = MD5Encode(sb.toString()).toUpperCase();
        return sign;
    }
    
    /**
     * MD5编码
     * @param origin 原始字符串
     * @return 经过MD5加密之后的结果
     */
    private static String MD5Encode(String origin) {
        String resultString = null;
        try {
            resultString = origin;
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(resultString.getBytes("UTF-8"));
            resultString = byteArrayToHexString(md.digest());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultString;
    }
    /**
     * 转换字节数组为16进制字串
     * @param b 字节数组
     * @return 16进制字串
     */
    private static String byteArrayToHexString(byte[] b) {
        StringBuilder resultSb = new StringBuilder();
        for (byte aB : b) {
            resultSb.append(byteToHexString(aB));
        }
        return resultSb.toString();
    }

    /**
     * 转换byte到16进制
     * @param b 要转换的byte
     * @return 16进制格式
     */
    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0) {
            n = 256 + n;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }
    
    private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7",
        "8", "9", "a", "b", "c", "d", "e", "f"};
    
    public static void main(String[] args) throws Exception {
		SortedMap<String, String> packageParams = new TreeMap<String, String>();
		packageParams.put("attachedData", "{merBillNo:2015090700000000}");
		packageParams.put("merOrderId", "2015090700000000");
		packageParams.put("targetOrderId", "2015090700000000");
		packageParams.put("buyerUsername", "张三");
		packageParams.put("status", "SUCCESS");
		packageParams.put("invoiceAmount", "800");
		packageParams.put("totalAmount", "1000");
		packageParams.put("billFunds", "COUPON:200|PCARD:800");
		packageParams.put("billFundsDesc", "优惠金额2.00元,银行卡支付金额8.00元");
		packageParams.put("payTime", "2015-09-07 16:00:00");
		String str = new SignUtil().createSign(packageParams);
		System.out.println(str);
	}
}

运行main方法即可获取代签名字符串

注:

没有值(包含空字符串)的参数无需传递,也不需包含到待签名数据中;

根据HTTP协议要求,传递参数的值中如果存在特殊字符(如:&、@等),则该值需要做URL Encoding,这样请求接收方才能接收到正确的参数值。注意:这种情况下,待签名数据应该是原始值而不是encoding之后的值。