Java中判断一个IP地址是否在一个网段内

要判断两个IP地址是不是在同一个网段,就将它们的IP地址分别与子网掩码做与运算,得到的结果一网络号,如果网络号相同,就在同一子网,否则,不在同一子网。

例如:假定选择了子网掩码255.255.254.0,现在分别将上述两个IP地址分别与掩码做与运算,如下图所示:

211.95.165.24 11010011 01011111 10100101 00011000
255.255.254.0 11111111 11111111 111111110 00000000

与的结果是: 11010011 01011111 10100100 00000000

211.95.164.78 11010011 01011111 10100100 01001110
255.255.254.0 11111111 11111111 111111110 00000000

与的结果是: 11010011 01011111 10100100 00000000

可以看出,得到的结果(这个结果就是网络地址)都是一样的,因此可以判断这两个IP地址在同一个子网。

例如:有一个C类地址为:192.9.200.13,按其IP地址类型,它的缺省子网掩码为:255.255.255.0,则它的网络号和主机号可按如下方法得到:
第1步,将IP地址192.9.200.13转换为二进制11000000 00001001 11001000 00001101
第2步,将子网掩码255.255.255.0转换为二进制11111111 11111111 11111111 00000000
第3步,将以上两个二进制数逻辑进行与(AND)运算,得出的结果即为网络部分。“11000000 00001001 11001000 00001101”与“11111111 11111111 11111111 00000000”进行“与”运算后得到“11000000 00001001 11001000 00000000”,即“192.9.200.0”,这就是这个IP地址的网络号,或者称“网络地址”。
第4步,将子网掩码的二进制值取反后,再与IP地址进行与(AND)运算,得到的结果即为主机部分。如将“00000000 00000000 00000000 11111111(子网掩码的取值)反”与“11000000 00001001 11001000 00001101”进行与运算后得到“00000000 00000000 00000000 00001101”,即“0.0.0.13”,这就是这个IP地址主机号(可简化为“13”)。

主机位中有3位被划为“网络标识号”占用,因网络标识号应全为“1”,所以主机号对应的字节段为“11100000”。转换成十进制后为224,这就最终确定的子网掩码。如果是C类网,则子网掩码为255.255.255.224;如果是B类网,则子网掩码为255.255.224.0;如果是A类网,则子网掩码为255.224.0.0。

实现方法一:

package com.nynu;

/**
 * @author ChenYanwei
 * @version 1.0
 */
public class TestIp {

    public static boolean isInRange(String network, String mask) {
        String[] networkips = network.split("\\.");
        int ipAddr = (Integer.parseInt(networkips[0]) << 24)
                | (Integer.parseInt(networkips[1]) << 16)
                | (Integer.parseInt(networkips[2]) << 8)
                | Integer.parseInt(networkips[3]);
        int type = Integer.parseInt(mask.replaceAll(".*/", ""));
        int mask1 = 0xFFFFFFFF << (32 - type);
        String maskIp = mask.replaceAll("/.*", "");
        String[] maskIps = maskIp.split("\\.");
        int cidrIpAddr = (Integer.parseInt(maskIps[0]) << 24)
                | (Integer.parseInt(maskIps[1]) << 16)
                | (Integer.parseInt(maskIps[2]) << 8)
                | Integer.parseInt(maskIps[3]);

        return (ipAddr & mask1) == (cidrIpAddr & mask1);
    }

    public static void main(String[] args) {
        System.out.println(isInRange("10.153.48.127", "10.153.48.0/26"));
        System.out.println(isInRange("10.168.1.2", "10.168.0.224/23"));
        System.out.println(isInRange("192.168.0.1", "192.168.0.0/24"));
        System.out.println(isInRange("10.168.0.0", "10.168.0.0/32"));
    }
}

结果:

false
true
true
true

实现方法二

package com.nynu;

/**
 * @author ChenYanwei
 * @version 1.1
 */
public class TestIp1 {

    public static boolean ipIsInNet(String iparea, String ip) {
        if (iparea == null)
            throw new NullPointerException("IP段不能为空!");
        if (ip == null)
            throw new NullPointerException("IP不能为空!");
        iparea = iparea.trim();
        ip = ip.trim();
        final String REGX_IP = "((25[0-5]|2[0-4]//d|1//d{2}|[1-9]//d|//d)//.){3}(25[0-5]|2[0-4]//d|1//d{2}|[1-9]//d|//d)";
        final String REGX_IPB = REGX_IP + "//-" + REGX_IP;
        if (!iparea.matches(REGX_IPB) || !ip.matches(REGX_IP))
            return false;
        int idx = iparea.indexOf('-');
        String[] sips = iparea.substring(0, idx).split("//.");
        String[] sipe = iparea.substring(idx + 1).split("//.");
        String[] sipt = ip.split("//.");
        long ips = 0L, ipe = 0L, ipt = 0L;
        for (int i = 0; i < 4; ++i) {
            ips = ips << 8 | Integer.parseInt(sips[i]);
            ipe = ipe << 8 | Integer.parseInt(sipe[i]);
            ipt = ipt << 8 | Integer.parseInt(sipt[i]);
        }
        if (ips > ipe) {
            long t = ips;
            ips = ipe;
            ipe = t;
        }
        return ips <= ipt && ipt <= ipe;
    }

    public static void main(String[] args) {
        System.out.println(ipIsInNet("10.153.48.127", "10.153.48.0/26"));
        System.out.println(ipIsInNet("10.168.1.2", "10.168.0.224/23"));
        System.out.println(ipIsInNet("192.168.0.1", "192.168.0.0/24"));
        System.out.println(ipIsInNet("10.168.0.0", "10.168.0.0/32"));
    }
}

结果:

false
false
false
false
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值