模糊匹配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,只要对这之间的数做一些分类讨论就行
- 长度是3的话,就直接沿用就行,也不用补齐
- 长度为2的话,则要再判断该小段数与10相乘后是否小于250,若是的话,开始段直接为本身,结束段则XX9补齐就好(例如16就是16-169)
- 如果等于1,则直接1-199
- 剩余的其他情况就是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;
}