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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章