我正在用Java编写一个小型API程序,它将验证IP地址。在最简单的迭代(1.2.3.4)
中,我只需要调用像googles guava这样的库,然后得到真或假。
我遇到的问题是输入可能包含ip范围,即192-198.10.12.16-20/24
由于guava不会将此类输入验证为有效的IP地址,因此我在调用guava之前尝试处理IP地址。
我以为我会做以下事情:
正如所解释的,我需要一种数据类型,它允许我存储主IP地址的八位字节和八位字节的IP范围(如果有的话)之间的原始关系,以便执行4中描述的检查并恢复原始IP地址表示法,即能够连接八位字节和IP范围。
想象上面我需要:
Octet 1 (192), IP Range 1 (198)
Octet 2 (10), IP Range 2 ()
Octet 3 (12), IP Range 3()
Octet 4 (16), IP Range 4 (20)
像String [][]
个八位字节这样的数组会做这个工作吗?如果是,我将如何填写?如果没有,那么其他数据类型适合什么?
答案 0 :(得分:2)
我建议使用自定义对象 - 可以在这里处理不同可能性的对象。
这将更加清晰和简单。最重要的是它可以有方法来处理不同的情况(例如,它可能有一个迭代器,它将返回IP地址对象覆盖的任何范围。
对只是一个坏主意(可读性明智),我只是建议找一些更有表现力的东西。
答案 1 :(得分:1)
public class IPAddress {
private IPOctet octet1;
private IPOctet octet2;
private IPOctet octet3;
private IPOctet octet4;
private static final String NETWORK_MASK_CHAR = "/24";
public IPAddress(String value) throws Exception{
value = cutOffNetworkMask(value);
String[] octets = value.split("\\.");
if (octets.length < 4) throw new Exception("Invalid input value. Too few octets.");
octet1 = new IPOctet(octets[0]);
octet2 = new IPOctet(octets[1]);
octet3 = new IPOctet(octets[2]);
octet4 = new IPOctet(octets[3]);
}
public boolean hasMatchOf(IPAddress another){
if (!octet1.isMatching(another.getOctet1())) return false;
if (!octet2.isMatching(another.getOctet2())) return false;
if (!octet3.isMatching(another.getOctet3())) return false;
if (!octet4.isMatching(another.getOctet4())) return false;
return true;
}
public IPOctet getOctet1(){ return octet1; }
public IPOctet getOctet2(){ return octet2; }
public IPOctet getOctet3(){ return octet3; }
public IPOctet getOctet4(){ return octet4; }
private static String cutOffNetworkMask(String base){
int index = base.indexOf(NETWORK_MASK_CHAR);
try{
if (index > -1) base = base.substring(0, index);
}catch(IndexOutOfBoundsException ignored){}
return base;
}
}
IPOctet类:
public class IPOctet {
private static final String RANGE_SYMBOL = "-";
int max = 255;
int min = 0;
public IPOctet(String stringValue) throws Exception {
int index = stringValue.indexOf(RANGE_SYMBOL);
if (index < 0){
// This octet is a single byte;
max = str2int(stringValue);
min = max;
}else{
// This octet has a range.
String[] values = stringValue.split(RANGE_SYMBOL);
if (values.length != 2) throw new Exception("Invalid Input. Range must be like xx-xx");
min = str2int(values[0]);
max = str2int(values[1]);
}
}
public boolean isMatching(IPOctet another) {
if (max < another.getMinValue()) return false;
if (min > another.getMaxValue()) return false;
return true;
}
public int getMinValue(){ return min; }
public int getMaxValue(){ return min; }
private static int str2int(String input) throws Exception{
int result;
try{
result = Integer.parseInt(input);
}catch(NumberFormatException nfe){
throw new Exception("Invalid input. Input is not a number.");
}
validate(result);
return result;
}
private static void validate(int input) throws Exception{
if (input < 0 || input > 255) throw new Exception("Invalid input. Must be between 0 and 255");
}
}
这是一个简单的测试案例:
public class Main {
public static void main(String[] args){
try{
IPAddress adr1 = new IPAddress("192.168.1.0-255");
IPAddress adr2 = new IPAddress("192.168.1.1/24");
IPAddress adr3 = new IPAddress("1.2.3.4");
System.out.println("adr2 matches adr1: " + adr1.hasMatchOf(adr2));
System.out.println("adr3 matches adr1: " + adr1.hasMatchOf(adr3));
}catch(Exception e){
System.err.println(e.getMessage());
}
}
}
有了这个,现在您可以将IPAddress
es存储在ArrayList
或LinkedList
中:
ArrayList<IPAddress> addresses = new ArrayList<>();
addresses.add(new IPAddress("8.8.8.8"));
addresses.add(new IPAddress("198.252.206.16"));
IPAddress mask = new IPAddress("20-200.200-255.100-255.0-255");
for (IPAddress addr : addresses){
if (mask.hasMatchOf(addr)){
...
}else{
..
}
}
答案 2 :(得分:0)
您不必将外部框架用于简单的作业/程序。使用正则表达式,您将能够简化程序并使其性能非常高。请查看以下链接:Regex to match Hostname or IP Address