检查有效的Java IPv4地址



我正在使用sun.net.util.IPAddressUtil包检查字符串是否包含有效的IPv4和IPv6地址。

代码片段为:-

String ipv4addr="200";
    if(IPAddressUtil.isIPv4LiteralAddress(ipv4addr))
    {
        System.out.println("valid ipv4 address");
    }
    else
    {
        System.out.println("not valid");
    }

但是对于像200和300这样的地址,它仍然说它是一个有效的IPv4地址,实际上它不是。当我使用相同的包和检查IPV6地址使用:-

String ipv6addr="200";
    if(IPAddressUtil.isIPv6LiteralAddress(ipv6addr))
    {
        System.out.println("valid ipv6 address");
    }
    else
    {
        System.out.println("not valid");
    }

我得到正确的结果。然而,IPv4似乎不工作,或者可能是我使用它不正确。请引导我。我不想使用正则表达式IPv4验证…

你得到一个"有效"的结果是有原因的:200 是一个有效的IPv4地址。

看,对于计算机来说,IPv4地址只是一个32位的数字。这些点完全是为了我们的方便,因为我们人类不擅长记忆大而精确的数字。但他们并不一定要在那里;地址被解析的规则取决于它有多少部分

当一个地址由一个数字组成时,它被认为是一个32位数字,每个字节是这个数字的8位。如果将"200"解析为IP地址,则等于0.0.0.200。同理,"2130706433"等于127.0.0.1。

当地址有两个部分时也有标准,如0.200(第一部分是第一个字节,第二部分是代表其他3个字节的24位数字),甚至0.0.200(前两个数字是字节,最后一部分是16位并占用其他2个字节)。这些"不寻常的"格式是IP地址类时代遗留下来的,但几乎所有必须解析地址的软件都能理解它们。(例如,如果你打开浏览器,进入http://1249739112 *,甚至http://74.125.33128 *,就会出现谷歌的主页。)

*请参阅评论中的可点击链接。谢谢"链接验证器"。: P

请参阅http://download.oracle.com/javase/6/docs/api/java/net/Inet4Address.html或http://www.perlmonks.org/?node_id=221512,或http://en.wikipedia.org/wiki/IPv4#Address_representations了解更多详细信息。

Java也能理解这些格式(就像。net,以及任何像样的操作系统一样),并正确解析地址,无论它包含1、2、3还是4部分。

如果你想检查一个潜在的地址实际上看起来像"xxx.xxx.xxx. xxx"。Xxx",那么您可能需要使用模式显式检查,或者使用将32位数字视为无效地址的验证库(即使它们是有效的)。不过,如果使用提供的查找函数,就可以接受任何标准格式的地址,并且可以正常工作。

(所有这些混乱的改变与IPv6;有一个更严格的格式,你不能只是输入一些36位数的数字,并期望它工作。但是平台仍然知道如何解析地址,您应该相信它可以这样做。

查看Guava的InetAddresses类,其中包含用于处理IP地址的静态实用程序方法。(据我所知,它在幕后使用sun.net.util.IPAddressUtil类。)

System.out.println(InetAddresses.isInetAddress("400")); // false

使用内部"sun"打包的类不是一个好主意,我会尝试使用Apache的Validator

http://commons.apache.org/validator/

如果要验证字符串是否为有效的IP地址表示,org.apache.http.conn.util.InetAddressUtils的源代码使用以下正则表达式:

IPV4_PATTERN = Pattern.compile(
    "^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$");
IPV6_STD_PATTERN = Pattern.compile(
    "^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$");
IPV6_HEX_COMPRESSED_PATTERN = Pattern.compile(
    "^((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)::((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)$");

该字符串是一种IPv4字符串格式,最初由BSD Unix中的aton_inet实用程序引入,并一直持续到今天在各种Unix和Linux版本以及其他地方。

https://linux.die.net/man/3/inet_aton

IPAddress Java库将进行验证,可以配置为支持或不支持aton_inet格式。javadoc可在链接中获得。免责声明:我是项目经理。

验证地址是否有效,允许inet_aton样式:

    String str = "200";
    IPAddressString addrString = new IPAddressString(str);
    try {
         IPAddress addr = addrString.toAddress();
         System.out.println("valid address: " + addr.toCanonicalString());
    } catch(IPAddressStringException e) {
        System.out.println(e.getMessage());
    }
输出:

有效地址:0.0.0.200

验证地址是否有效,不允许inet_aton样式:

    IPAddressStringParameters parameters = new       
      IPAddressStringParameters.Builder().allow_inet_aton(false).toParams();
    addrString = new IPAddressString(str, parameters);
    try {
         IPAddress addr = addrString.toAddress();
         System.out.println("valid address: " + addr.toCanonicalString());
    } catch(IPAddressStringException e) {
        System.out.println(e.getMessage());
    }
输出:

200 IP地址错误:选项不允许IPv4地址少于四个段

经过一番小小的研究,我最终得到了这样的东西

    public static boolean isValidIP4Address(String ipAddress) {
        if (ipAddress.matches("^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$")) {
            String[] groups = ipAddress.split("\.");
            for (int i = 0; i <= 3; i++) {
                String segment = groups[i];
                if (segment == null || segment.length() <= 0) {
                    return false;
                }
                int value = 0;
                try {
                    value = Integer.parseInt(segment);
                } catch (NumberFormatException e) {
                    return false;
                }
                if (value > 255) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

最新更新