模糊匹配IP的一种实现方式

模糊匹配IP的一种实现方式

组内有一个需求,要求可以对用户输入的IP进行模糊匹配出相关的结果集。

这里的模糊是指,用户可以输入不完整的IP,例如:10.58和192.16.2.,当然IP地址每一段仍需符合IP的格式,当不完整的IP传给后台后,需要补齐成一个IP区间,10.58要匹配成10.58.0.0-10.58.255.255,192.16要匹配成192.16.0.0-192.169.255.255,再在数据层进行筛选。

(现记录一下我自己的实现方式)

对不完整的IP正则校验

//模糊IP正则
//这个正则还有一点点小的缺陷,当IP是空字符串的话也能通过,所以得先提前校验一下非空字符串
String ip = "192.16";
String regex = "((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)\\.){0,3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)?";
Pattern p = Pattern.compile(regex);
if(p.matcher(ip).matches()) {
	System.out.println("是有效IP");
} else {
	System.out.println("非有效IP");
}

对IP补齐

其实不完整的IP,主要是最后一个不完整的段需要补齐,空的部分直接补0或是255就行。IPv4总共有四小段,每一段的范围都是0-255,只要对这之间的数做一些分类讨论就行

  1. 长度是3的话,就直接沿用就行,也不用补齐
  2. 长度为2的话,则要再判断该小段数与10相乘后是否小于250,若是的话,开始段直接为本身,结束段则XX9补齐就好(例如16就是16-169)
  3. 如果等于1,则直接1-199
  4. 剩余的其他情况就是field-255

下面给出总体的代码

/**
     * 获得模糊IP区间
     * @param ip 模糊IP
     * 例如192.16会返回192.16.0.0-192.169.255.255这样的区间范围
     * @return
     */
    public static String[] getIndistinctIpRange(String ip) {
        //模糊IP正则
        String regex = "((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)\\.){0,3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)?";
        if (Pattern.compile(regex).matcher(ip).matches()) {
            String[] range = new String [2];
            String[] ipFields = ip.split("\\.");
            int length = ipFields.length;
            //最后一小段的波动范围
            String lastField = ipFields[length - 1];
            String[] lastFieldRange = getFieldRange(lastField);
            //返回区间的开始段
            StringBuilder ipFromBuilder = new StringBuilder();
            for (int i = 0; i < length - 1; i ++) {
                ipFromBuilder.append(ipFields[i]).append(".");
            }
            //返回区间的结束段
            StringBuilder ipToBuilder = new StringBuilder(ipFromBuilder.toString());
            ipFromBuilder.append(lastFieldRange[0]);
            ipToBuilder.append(lastFieldRange[1]);
            for (int i = length; i < 4; i ++) {
                ipFromBuilder.append(".0");
                ipToBuilder.append(".255");
            }
            range[0] = ipFromBuilder.toString();
            range[1] = ipToBuilder.toString();
            return range;
        } else {
            throw new RuntimeException("Invalid IP");
        }
    }

    /**
     * IP地址某一小段补齐的模糊范围
     * 例如25应返回25-255    9应返回9-255   16应返回16-169
     * @param field 小段的值应在0-255之间
     * @return
     */
    private static String[] getFieldRange(String field) {
        String[] range = new String[2];
        if (field.length() == 3) {
            range[0] = field;
            range[1] = field;
        } else if (field.length() == 2 && Integer.parseInt(field) * 10 < 250) {
            range [0] = field;
            range [1] = field + "9";
        } else if (field.equals("1")) {
            range [0] = field;
            range [1] = field + "99";
        } else {
            range [0] = field;
            range [1] = "255";
        }
        return range;
    }
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值