【问题标题】:Check whether the ipAddress is in private range检查 ipAddress 是否在私有范围内
【发布时间】:2020-06-07 07:13:56
【问题描述】:

如何查看该 IP 地址是否属于私有类别?

    if(isPrivateIPAddress(ipAddress)) {
        //do something
    }

任何建议将不胜感激。

更新答案

    private static boolean isPrivateIPAddress(String ipAddress) {

            InetAddress ia = null;

            try {
                InetAddress ad = InetAddress.getByName(ipAddress);
                byte[] ip = ad.getAddress();
                ia = InetAddress.getByAddress(ip);
            } catch (UnknownHostException e) {
                e.printStackTrace();
                return false;
            }

            return ia.isSiteLocalAddress();
        }

我写了这个方法,它对我来说很好用。但是有没有这种方法行不通的情况?我只是想确保它适用于每种情况。

【问题讨论】:

标签: java


【解决方案1】:

正确的方法是InetAddress.isSiteLocalAddress()

检查 InetAddress 是否为站点本地地址的实用程序。

返回:一个布尔值,指示 InetAddress 是否为本地站点 地址;如果地址不是站点本地单播地址,则为 false。

【讨论】:

  • 你能在此基础上举一个例子吗?非常感谢。谢谢
【解决方案2】:

首先,专用网络可以在以下范围内的任何地方使用 IPv4 地址:

  • a) 192.168.0.0 - 192.168.255.255(65,536 个 IP 地址)
  • b) 172.16.0.0 - 172.31.255.255(1,048,576 个 IP 地址)
  • c) 10.0.0.0 - 10.255.255.255(16,777,216 个 IP 地址)

我们可以从 Inet4Address.java 中的 isSiteLocalAddress 方法看到:

 public boolean isSiteLocalAddress() {
    // refer to RFC 1918
    // 10/8 prefix
    // 172.16/12 prefix
    // 192.168/16 prefix
    int address = holder().getAddress();
    return (((address >>> 24) & 0xFF) == 10)
        || ((((address >>> 24) & 0xFF) == 172)
            && (((address >>> 16) & 0xF0) == 16))
        || ((((address >>> 24) & 0xFF) == 192)
            && (((address >>> 16) & 0xFF) == 168));
}

所以情况 b) 172.16.0.0 - 172.31.255.255(1,048,576 个 IP 地址)不满足。但是您可以轻松编写自己的版本来判断地址是否为私有地址。这是我的版本:

import com.google.common.net.InetAddresses;

private static boolean isPrivateV4Address(String ip) {
    int address = InetAddresses.coerceToInteger(InetAddresses.forString(ip));
    return (((address >>> 24) & 0xFF) == 10)
            || ((((address >>> 24) & 0xFF) == 172) 
              && ((address >>> 16) & 0xFF) >= 16 
              && ((address >>> 16) & 0xFF) <= 31)
            || ((((address >>> 24) & 0xFF) == 192) 
              && (((address >>> 16) & 0xFF) == 168));
}

【讨论】:

  • 这个答案不正确。情况 b) 满足,因为掩码是 0xF0。测试 InetAddress.getByName("172.31.255.255").isSiteLocalAddress() 返回 true 很简单。
【解决方案3】:

这是我为测试我自己的地址而生成的一个快速破解方法。

import java.net.InetAddress;
import java.net.UnknownHostException;

public class LocalAddress {

    public static void main(String[] args) {
        InetAddress address = null;
        try {
            address = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
             e.printStackTrace();
        }
        if (address.isSiteLocalAddress()) {
            System.out.println("Site Local Address: " + address.getHostAddress());
        } else {
            System.out.println("Routeable Address: " + address.getHostAddress());
        }
    }

}

编辑:此代码尚未针对链接本地地址、本地主机或为文档保留的地址块进行测试。前两种情况有返回它们的方法。最后一个没有在类的文档中引用。

【讨论】:

  • 如果我需要检查一些随机的 ipAddress 那么我该怎么做呢?假设 ipAddress 是 172.18.36.81
  • getLocalHost() 替换为getByName("172.18.36.81")。阅读 InetAddress 的 JavaDoc。
【解决方案4】:

我用这个:

public boolean isPrivateIP(String ipAddress) {
        boolean isValid = false;

        if (ipAddress != null && !ipAddress.isEmpty()) {
            String[] ip = ipAddress.split("\\.");
            short[] ipNumber = new short[] { 
                    Short.parseShort(ip[0]), 
                    Short.parseShort(ip[1]), 
                    Short.parseShort(ip[2]),
                    Short.parseShort(ip[3])
                };

            if (ipNumber[0] == 10) { // Class A
                isValid = true;
            } else if (ipNumber[0] == 172 && (ipNumber[1] >= 16 && ipNumber[1] <= 31)) { // Class B
                isValid = true;
            } else if (ipNumber[0] == 192 && ipNumber[1] == 168) { // Class C
                isValid = true;
            }
        }

        return isValid;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 2017-07-13
    • 2021-03-30
    • 2016-05-03
    • 2015-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多