使用Java测试两个IP是否在同一个网络中

9

如何根据子网掩码测试两个IP是否在同一网络中?

例如,我有IP地址1.2.3.4和1.2.4.3:如果子网掩码为255.0.0.0或255.255.0.0甚至是255.255.248.0,则两者都在同一网络中,但如果子网掩码为255.255.255.0,则不在同一网络中。

3个回答

15

试试这个方法:

public static boolean sameNetwork(String ip1, String ip2, String mask) 
throws Exception {

    byte[] a1 = InetAddress.getByName(ip1).getAddress();
    byte[] a2 = InetAddress.getByName(ip2).getAddress();
    byte[] m = InetAddress.getByName(mask).getAddress();

    for (int i = 0; i < a1.length; i++)
        if ((a1[i] & m[i]) != (a2[i] & m[i]))
            return false;

    return true;

}

然后像这样使用:

sameNetwork("1.2.3.4", "1.2.4.3", "255.255.255.0")
> false

编辑:

如果您已经拥有代表 IP 的 InetAddress 对象:

public static boolean sameNetwork(InetAddress ip1, InetAddress ip2, String mask) 
throws Exception {

    byte[] a1 = ip1.getAddress();
    byte[] a2 = ip2.getAddress();
    byte[] m = InetAddress.getByName(mask).getAddress();

    for (int i = 0; i < a1.length; i++)
        if ((a1[i] & m[i]) != (a2[i] & m[i]))
            return false;

    return true;

}

不错的解决方案 - 避免了自己解析字符串的麻烦。 - Voo
我已经有IP地址本身作为InetAddresses,所以最多只需要解析掩码。 - xZise
@xZise 我编辑了我的答案以匹配您的最后一条评论。请注意,如果掩码对于所有比较都相同,则最好只计算它的byte[]地址一次并重复使用它。 - Óscar López

5

很简单: mask & ip1 == mask & ip2 - 你需要将这些IP地址解释为一个整数,但这应该很明显。


@xZise 子网掩码是您的子网掩码。当然,对于IPv6,它也可以正常工作 - 只是与IPv4相比有不同的表示法。但最终您只需使用子网掩码来屏蔽IP的网络部分,然后将其彼此进行比较即可。 - Voo
但是如何从程序本身获取子网掩码? - xZise
@xZise 抱歉,我不理解你的问题。你想要最具体的子网掩码,以便2个IP在同一网络中吗?否则,在没有子网掩码的情况下,你无法回答这个问题,是否两个IP在同一网络中(这最终取决于掩码)。 - Voo
没有办法在不询问用户的情况下确定子网掩码吗? - xZise
@xZise 我认为InetAddress不会存储那些信息,但即使它存储了 - 它本身从哪里获取信息呢?无论如何,您需要从用户(或其配置 - 如果是本地进程,则可以从操作系统中读取信息)获取该信息,这是无法避免的。 - Voo

0

这个解决方案也适用于IPv4/IPv6。

static boolean sameNetwork(final byte[] x, final byte[] y, final int mask) {
    if(x == y) return true;
    if(x == null || y == null) return false;
    if(x.length != y.length) return false;
    final int bits  = mask &   7;
    final int bytes = mask >>> 3;
    for(int i=0;i<bytes;i++)  if(x[i] != y[i]) return false;
    final int shift = 8 - bits;
    if(bits != 0 && x[bytes]>>>shift != y[bytes]>>>shift) return false;
    return true;
}
static boolean sameNetwork(final InetAddress a, final InetAddress b, final int mask) {
    return sameNetwork(a.getAddress(), b.getAddress(), mask);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接