网络请求参数加签处理

news/2024/5/19 23:36:52 标签: android, 快速排序

网络请求的中,有的数据是敏感数据,需要加密处理,同时为了防止数据在网络请求过程中被窜改,可以通过加签的形式进行处理,即把关键的参数进行拼接再加上一个秘钥(可以是登录操作时获取并存在本地的),形成一个新的字符串,然后对字符串进行MD5加密,得到一个签,连同请求参数一起传给后台,后台也用同样的方法生成一个签,进行比对,如果一样说明数据没有变动,如果不一样,说明数据在网络请求过程中被改动。


public class RequestHandler {
    protected static final String CHARSET = "UTF-8";

    /**
     * 描述:创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名
     */
    public static String createSign(Map<String, String> param) {
        SortedMap packageParams = new TreeMap<String, String>(param);
        StringBuffer sb = new StringBuffer();
        Set<Entry<String, String>> es = packageParams.entrySet();
        Iterator<Entry<String, String>> it = es.iterator();
        while (it.hasNext()) {
            Entry<String, String> entry = (Entry<String, String>) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (!TextUtils.isEmpty(v) && !"sign".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        String str = MD5Util.hmacSign(sb.substring(0, sb.length() - 1), HSDApplication.getOption());
        String sign = TextUtils.isEmpty(str) ? "" : str.toUpperCase();
        return sign;
    }

    /**
     * 描述:特殊字符处理
     */
    private static String UrlEncode(String src) {
        try {
            return URLEncoder.encode(src, CHARSET).replace("+", "%20");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return "";
        }
    }


    static  class MD5Util {
        public static final String ENCODE = RequestHandler.CHARSET;

        public static String hmacSign(String aValue, String aKey) {
            byte k_ipad[] = new byte[64];
            byte k_opad[] = new byte[64];
            byte keyb[];
            byte value[];
            try {
                keyb = aKey.getBytes(ENCODE);
                value = aValue.getBytes(ENCODE);
            } catch (UnsupportedEncodingException e) {
                keyb = aKey.getBytes();
                value = aValue.getBytes();
            }
            Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);
            Arrays.fill(k_opad, keyb.length, 64, (byte) 92);
            for (int i = 0; i < keyb.length; i++) {
                k_ipad[i] = (byte) (keyb[i] ^ 0x36);
                k_opad[i] = (byte) (keyb[i] ^ 0x5c);
            }

            MessageDigest md = null;
            try {
                md = MessageDigest.getInstance("MD5");
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
                return null;
            }
            md.update(k_ipad);
            md.update(value);
            byte dg[] = md.digest();
            md.reset();
            md.update(k_opad);
            md.update(dg, 0, 16);
            dg = md.digest();
            return MD5Util.toHex(dg);
        }

        private static String toHex(byte input[]) {
            if (input == null)
                return null;
            StringBuffer output = new StringBuffer(input.length * 2);
            for (int i = 0; i < input.length; i++) {
                int current = input[i] & 0xff;
                if (current < 16)
                    output.append("0");
                output.append(Integer.toString(current, 16));
            }

            return output.toString();
        }
    }
}

如上方法中,将需要做加签处理的参数组成map对象,传递动createSign方法中,得到一个签,并在网络请求中将其当做参数传递给后台即可



这里涉及到一个问题,即参数自动排序,如aa=123,和ab=456,de =789,三个参数需要按照一定顺序排序,让后台的程序也能按照同样的顺序排序,从而保证结果不变。 如果每一个网络请求单独去拼接字符串就太麻烦了 ,所以要用统一的处理方式。 

这里使用的是SortedMap


SortedMap接口是排序接口,只要是实现了此接口的子类,都属于排序的子类,TreeMap是SortedMap接口的基于红黑树的实现。此类保证了映射按照升序顺序排列关键字, 根据使用的构造方法不同,可能会按照键的类的自然顺序进行排序(参见 Comparable), 或者按照创建时所提供的比较器进行排序。 。SortedMap接口的定义如下:

public interface SortedMap<K,V>  
extends Map<K,V> 

保证按照键的升序排列的映射,可以按照键的自然顺序(参见 Comparable 接口)进行排序, 或者通过创建有序映射时提供的比较器进行排序。对有序映射的集合视图 (由 entrySet、keySet 和 values 方法返回)进行迭代时,此顺序就会反映出来。
 要采用此排序,还需要提供一些其他操作(此接口是相似于 SortedSet 接口的映射)。
 插入有序映射的所有键都必须实现 Comparable 接口(或者被指定的比较器所接受)。
 另外,所有这些键都必须是可互相比较的:k1.compareTo(k2)(或 comparator.compare(k1, k2)) 对有序映射中的任意两个元素 k1 和 k2 都不得抛出 ClassCastException。
 试图违反这些限制将导致违反方法或者构造方法的调用,从而抛出 ClassCastException。
 注意,如果有序映射正确实现了 Map 接口,则有序映射所保持的顺序(无论是否明确提供了比较器)都必须保持相等一致性。
 (相等一致性 的精确定义请参阅 Comparable 接口或 Comparator 接口)。
 这也是因为 Map 接口是按照 equals 操作定义的,但有序映射使用它的 compareTo(或 compare)方法对所有键进行比较, 因此从有序映射的观点来看,此方法认为两个对象拥有相等的映射键则说明它们是相等的。
 即使顺序没有保持相等一致性,树映射的行为仍然是 定义良好的,只不过没有遵守 Map 接口的常规协定。
 所有通用有序映射实现类都应该提供 4 个“标准”构造方法:
 1) void(不带参数)构造方法,创建空的有序映射,按照键的自然顺序 排序。
 2) 带有一个 Comparator 类型参数的构造方法,创建一个空的有序映射,根据指定的比较器排序。
 3) 带有一个 Map 类型参数的构造方法,创建一个键-值映射关系与参数相同的有序映射,按照键的自然顺序排序。
 4) 带有一个有序映射类型参数的构造方法,创建一个新的有序映射,键-值映射关系及排序方法与输入的有序映射相同。如:TreeMap(SortedMap<K,? extends V> m) 
 除了 JDK 实现(TreeMap 类)遵循此建议外,无法保证强制实施此建议(因为接口不能包含构造方法)。
SortedMap声明的接口


在此接口上定义了一些Map中没有的方法,表13-14  SortedMap接口扩展的方法

 







http://www.niftyadmin.cn/n/1678150.html

相关文章

I/O多路复用和Socket

原文&#xff1a;I/O多路复用和Socket 由于IO操作涉及到系统调用&#xff0c;涉及到用户空间和内核空间的切换&#xff0c;所以理解系统的IO模型&#xff0c;对于需要进入到系统调用层面进行编程来说是很重要的。 阻塞IO和非阻塞IO 从程序编写的角度来看&#xff0c;I/O就是调用…

Hibernate关联关系(多对多)

目录1.Hibernate关联关系&#xff08;多对多&#xff09;2.案例3.开始写dao方法4.junit5.效果6.总结&#xff1a;1.Hibernate关联关系&#xff08;多对多&#xff09; 1.1数据库中不能直接映射多对多 处理&#xff1a;创建一个桥接表(中间表)&#xff0c;将一个多对多关系转换成…

js中判断浏览器类型

在实际看发展&#xff0c;有时候会遇到在IOS和Android中要用不同的方法处理网页&#xff0c;需要让网页返回当前浏览器的类型。 /*** 判断浏览器类型*/ var Browse function () {//判断是否是苹果系统this.browseIos function () {var ua navigator.userAgent.toLowerCase()…

Hibernate之HQL

目录1.什么是hql2.hql和sql区别/异同3.案例1.什么是hql HQL是Hibernate Query Language的缩写 2.hql和sql区别/异同 HQLSQL类名/属性表名/列名区分大小写,关键字不区分大小写不区分大小写别名别名?&#xff0c;从下标0开始计算位置(hibernate5之后不支持)?&#xff0c;从顺…

关于显存

在IA-32架构中&#xff0c;显存映射的内存范围是0xA0000 - 0xBFFFF&#xff0c;共128KB。 如果是单色显示&#xff0c;则显存从地址范围0xB0000开始使用&#xff0c;可用长度为4KB 如果是彩色显示&#xff0c;则显存从地址范围0xB8000开始使用&#xff0c;可用长度为16K。 VGA显…

数据结构复习之【排序】

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 目录(?)[] 排序&#xff1a;对一序列对象根据某个关键字进行排序&#xff1b; 稳定&#xff1a;如果a原本在b前面&#xff0c;而ab&#xff0c;排序之后a仍然在b的前面&#xff1b; 不稳定&#xf…

Hibernate之二级缓存

目录1.为什么需要缓存2.什么样的数据需要缓存3.ehcache是什么4.ehcache的特点5.案例6.Hibernate如何导入二级缓存&#xff08;ehcache&#xff09;7. 指定实体类开启二级缓存8.hibernate针对单条数据和多条数据使用二级缓存为什么存在差异性呢&#xff1f;1.为什么需要缓存 1.…

少走弯路:学习编译原理的相关建议

少走弯路:学习编译原理的相关建议 编译原理一般认为是较难的一门课.从网上的评论来看,有人说学了一年半软件理论,就一门编译看不懂;有人甚至说它是大本软件课程里最难的一门;有人抱怨国内的编译教材没有一本容易懂的。 从笔者学习实践来看,第一次学了一个多月,理论部分一知半解…