方便快捷的HTTP匹配

        Http中常用到添加白名单,现在的业务是针对每一个ip配置不同的匹配规则来达到权限控制,这样,针对同一个ip在不能出现重复规则。


       因为用户输入的内容是复杂的,允许单个输入ip,也允许输入ip地址段,因此,需要提供一个工具类来匹配该ip是否已经存在。


      整体思想,讲用户输入的所有ip和ip段放入list集合中,在工具类调用时,将单个ip存放入list中,地址段转化为Map<Long,Long>类型,这样,在新添加的ip进行匹配时,只要匹配这两种类型即可:

/**
 * @author whp 17-12-4
 */
@Component
public class IPMatchUtils {
    private Map<Long,Long> purMap=new HashMap<>();
    private List<String> purList=new ArrayList<>();

    //记录已经配置过的ip
    public static String configuredIp;
    //记录非法ip
    public static String illegalIp;

    public IPMatchUtils(){};

    //该方法匹配两个list,res是要匹配的ip集合,pus是已经存在的ip集合
    public Boolean isUnique(List<String> res,List<String> pur){
        splitPurpose(pur);
        Boolean flag=true;
        for (String ip:res) {
            if(ip.contains("-")){
                String[] ips=ip.split("-");
                flag=(matchIp(ips[0]) && matchIp(ips[1]));
            }else{
                flag=matchIp(ip);
            }
            if(!flag){
                illegalIp=ip;
                return flag;
            }
        }
        return flag;
    }

    //匹配单个ip或者ip段
    public Boolean isMached(String ip,List<String> pur){
        splitPurpose(pur);
        Boolean flag=true;
        if(ip.contains("-")){
            String[] ips=ip.split("-");
            flag=(matchIp(ips[0]) && matchIp(ips[1]));
        }else{
            flag=matchIp(ip);
        }
        return (!flag);
    }

    private Boolean matchIp(String strIP){
        Boolean flag=true;
        if(purList.contains(strIP)){ //单个ip匹配只要ip集合中包含该ip即存在
            configuredIp=strIP;
            return false;
        }
        flag=matchIpAddressBlock(strIP);
        return flag;
    }

   //将ip转化为long类型数字
    private Long translateIpToLongNum(String strIp){
        Long ips = 0L;
        String[] numbers = strIp.split("\\.");
        //等价上面
        for (int i = 0; i < 4; ++i) {
            ips = ips << 8 | Integer.parseInt(numbers[i]);
        }
        return ips;
    }

    // 将ip分为单ip集合与ip段map
    private void splitPurpose(List<String> list){
        for (String ip:list) {
            if(ip.contains("-")){
                String[] ips=ip.split("-");
                Long start=translateIpToLongNum(ips[0]);
                Long end=translateIpToLongNum(ips[1]);
                if(start<end){
                    purMap.put(start,end);
                }else{
                    purMap.put(end,start);
                }
            }else{
                purList.add(ip);
            }
        }
    }

    private Boolean matchIpAddressBlock(String strIp){
        Iterator<Map.Entry<Long,Long>> it=purMap.entrySet().iterator();
        Long numIp=translateIpToLongNum(strIp);
        while (it.hasNext()){
            Map.Entry entry=it.next();
            if(numIp>=Long.parseLong(entry.getKey().toString()) && numIp<=Long.parseLong(entry.getValue().toString())){
                configuredIp=numberToIp(Long.parseLong(entry.getKey().toString()))+"-"+numberToIp(Long.parseLong(entry.getValue().toString()));
                return false;
            }
        }
        return true;
    }
    //将数字转化为ip
    private String numberToIp(long number){
        String ip = "";
        for (int i = 3; i >= 0; i--) {
            ip  = String.valueOf((number & 0xff))+ip;
            if(i != 0){
                ip = "."+ip;
            }
            number = number >> 8;
        }
        return ip;
    }

}


       

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值