【问题标题】:Check if an IP is contained in a set of ranges?检查 IP 是否包含在一组范围中?
【发布时间】:2018-04-16 21:01:50
【问题描述】:

有谁知道检查 IP 是否包含在一组范围内的干净方法?

我收到如下回复:

"ipRange": "10.12.0.0/16,10.80.0.0/15,10.83.0.0/16,10.101.0.0-10.103.255.255,10.108.0.0/16,10.121.0.0/16,10.123.0.0/16,10.127.0.0/16,10.129.0.0/16,10.131.0.0/16,10.133.0.0/16,10.135.0.0-10.139.255.255,10.208.0.0/14,10.215.0.0/16,10.218.0.0/15,10.233.0.0/16,172.17.128.0-172.19.255.255,172.24.0.0/15,192.168.0.0/16"

而且我需要查看这些作品中是否有 IP。带有“斜线”符号的那些应该是直截了当的,但是它们带有“-”的范围呢?

【问题讨论】:

  • 它有不同的网络和子网
  • 这似乎是解析结果字符串,将 IP 转换为纯数字 32 位数字,识别每组 IP 的范围,最后使用比较器检查目标 IP 的问题IP 范围 - 33 位数字格式。
  • 你试过下面的库吗(不知道有没有用)? github.com/edazdarevic/CIDRUtils
  • 你需要的是来自 Apache Commons / Net 的 SubNetUtils

标签: java subnet


【解决方案1】:

IPv4 地址只不过是一个无符号的 int32。检查带有网络掩码 X 的 IP 地址 A 是否在带有网络掩码 Y 的子网 B 中的简单方法:

  1. 将 A 转换为 uint32
  2. 将 B 转换为 uint32
  3. 将 Y 转换为 uint32
  4. 如果 (A & Y) == (B & Y) 那么是

【讨论】:

    【解决方案2】:

    我已经评论了下面的代码。基本上,我通过查找“,”将“ipRanges”拆分为不同的 ipAddresses 或 ipAddressRanges。然后对每个给定的 ip 进行测试,看看它是否良好。

    String ipRange = "10.12.0.0/16,10.80.0.0/15,10.83.0.0/16,10.101.0.0-10.103.255.255,10.108.0.0/16,10.121.0.0/16,10.123.0.0/16,10.127.0.0/16,10.129.0.0/16,10.131.0.0/16,10.133.0.0/16,10.135.0.0-10.139.255.255,10.208.0.0/14,10.215.0.0/16,10.218.0.0/15,10.233.0.0/16,172.17.128.0-172.19.255.255,172.24.0.0/15,192.168.0.0/16";
    
    
    public IPAddressTest() {
        String ipToTest = "10.101.0.0";
        System.out.println(String.format("[%s] is in range (%b)", ipToTest, isInRange(ipToTest)));
    }
    
    private Boolean isInRange(String ipToTest) {
        String[] ranges = ipRange.split(",");
    
        for (String _range : ranges) {
            String range = _range.indexOf("/") > -1 ? _range.substring(0, _range.indexOf("/")) : _range; // cut off the /xx if it exists
            boolean test = test(ipToTest, range);
            if (test) {
                return true;
            }
        }
    
        return false;
    }
    
    private Boolean test(String ipToTest, String ipRange) {
        String[] ranges = ipRange.split("-"); // Do we have a range or just a single ip
        String loRange = ranges[0]; // grab the first
        String hiRange = ranges.length > 1 ? ranges[1] : null; // If there a range grab the top end, else nothing
    
        if (hiRange == null) { // if a single ip, just do a string compare
            return ipToTest.equals(loRange);
        } else { // if a range then make sure each part is between the min and max
            String[] partsToTest = ipToTest.split("\\."); // get each part of the ip
            String[] partsLoRange = loRange.split("\\."); // get each part of the ip
            String[] partsHiRange = hiRange.split("\\."); // get each part of the ip
            int test = 0; // this will be our litmus test. if it = 15 when we are done, then each part is good, 63 of ipv6
            for (int i = 0; i < 4; i++) { // change 4 to 6 for ipv6
                int value = Integer.parseInt(partsToTest[i]); //get the int
                int lo = Integer.parseInt(partsLoRange[i]); //get the int
                int hi = Integer.parseInt(partsHiRange[i]); //get the int
                if (value >= lo && value <= hi) { // if we have a good value, set the bit on 'test'
                    test += Math.pow(2, i);
                }
            }
            if (test == 15) {
                return true;
            }
        }
    
        return false;
    }
    
    public static void main(String[] args) {
        new IPAddressTest();
    }
    

    【讨论】:

    • 这看起来您没有正确处理 CIDR 掩码。像 10.12.0.0/16 这样的条目已经匹配了 65,535 个地址。
    猜你喜欢
    • 2010-12-09
    • 2014-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    • 2018-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多