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;
}
}