如何在Java中存储对?

时间:2013-04-09 22:09:52

标签: java types

我正在用Java编写一个小型API程序,它将验证IP地址。在最简单的迭代(1.2.3.4)中,我只需要调用像googles guava这样的库,然后得到真或假。

我遇到的问题是输入可能包含ip范围,即192-198.10.12.16-20/24

由于guava不会将此类输入验证为有效的IP地址,因此我在调用guava之前尝试处理IP地址。

我以为我会做以下事情:

  1. 切断网络掩码(此处为/ 24)(如果有)。
  2. 使用split(“\。”)方法将八位字节分隔为字符串数组(?)。
  3. 将八位字节的IP范围提取到一个单独的字符串数组中,因此八位字节数组只包含主IP地址,我现在可以将其传递给guava进行验证。
  4. 作为最后一步,我会检查给定的IP范围是否大于它所属的八位位组,并且更小256.如果是,那么原始IP地址(见上文)就可以了。
  5. 正如所解释的,我需要一种数据类型,它允许我存储主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 [][]个八位字节这样的数组会做这个工作吗?如果是,我将如何填写?如果没有,那么其他数据类型适合什么?

3 个答案:

答案 0 :(得分:2)

我建议使用自定义对象 - 可以在这里处理不同可能性的对象。

这将更加清晰和简单。最重要的是它可以有方法来处理不同的情况(例如,它可能有一个迭代器,它将返回IP地址对象覆盖的任何范围。

对只是一个坏主意(可读性明智),我只是建议找一些更有表现力的东西。

答案 1 :(得分:1)

比尔K说得对。这是一个简单的示例类:

    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存储在ArrayListLinkedList中:

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