在 Java 中验证 IPv4 地址

Posted

技术标签:

【中文标题】在 Java 中验证 IPv4 地址【英文标题】:Validate IPv4 address in Java 【发布时间】:2011-08-05 18:13:20 【问题描述】:

我想使用 Java 验证 IPv4 地址。它应该使用dot-decimal notation 编写,所以它应该有3 个点(“.”),没有字符,点之间有数字,并且数字应该在有效范围内。应该怎么做?

【问题讨论】:

请注意,并非所有技术上有效的 IP 地址符号都具有三个点,只有 IP 地址的点符号具有它们。还要注意 ipv6,您可能希望也可能不希望将私有地址空间与公共地址空间分开。 如果您能将接受的答案更改为 worpet 的答案,我认为世界上所有的代码审查者都会非常感激 :) @samthebest :哦。我很久以前就问过这个问题,并接受了当时对我有用的答案。 感谢@iRunner,这是有道理的。幸运的是,堆栈溢出确实允许您更改接受的答案,这不会招致任何惩罚。该功能恰好适用于这种情况,即新的更好的答案比原始答案出现得晚得多。请您试一试并接受 Worpet 的回答吗? 【参考方案1】:

使用正则表达式非常简单(但请注意,这比使用 Apache Commons 实用程序的 worpet's answer 效率低得多,也更难阅读)

private static final Pattern PATTERN = Pattern.compile(
        "^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.)3([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");

public static boolean validate(final String ip) 
    return PATTERN.matcher(ip).matches();

基于帖子Mkyong

【讨论】:

哦,它不能在 android 上运行。当应用程序启动时,它会给出强制关闭错误 格式奇特的 IP 地址,比如 127.1(相当于 127.0.0.1)呢? IPv6 呢? 你可以简单的写成:return ip != null && ip.matches(PATTERN) 正则表达式的一个潜在问题是它似乎与 010.020.030.040 之类的内容匹配,但这可能会出现问题,因为以 0 开头的数字通常可以解释为八进制数。 没错!这错过了领先的 0 案例。 @Akarshit Wal 的解决方案效果更好。【参考方案2】:

试试 InetAddressValidator 实用程序类。

文档在这里:

http://commons.apache.org/validator/apidocs/org/apache/commons/validator/routines/InetAddressValidator.html

在这里下载:

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

【讨论】:

最好使用已经编写好的实用程序来处理这些事情 警告:这会将 commons-logging 拖到你的类路径中,这可能会产生意想不到的副作用。如果你不想这样,你可能更喜欢下面的 Guava 选项......【参考方案3】:

使用Guava的

InetAddresses.isInetAddress(ipStr)

【讨论】:

实际上有isInetAddress 方法,如果地址有效则返回true/false。这比检查异常要干净一些;)。 我已编辑帖子以更新链接并切换到更直接的布尔返回方法,谢谢!【参考方案4】:

请参阅https://***.com/a/5668971/1586965,它使用 apache 公共库 InetAddressValidator

或者你可以使用这个功能 -

public static boolean validate(final String ip) 
    String PATTERN = "^((0|1\\d?\\d?|2[0-4]?\\d?|25[0-5]?|[3-9]\\d?)\\.)3(0|1\\d?\\d?|2[0-4]?\\d?|25[0-5]?|[3-9]\\d?)$";

    return ip.matches(PATTERN);

【讨论】:

谢谢!这是唯一对我有用的。其他正则表达式模式都错过了前导 0 的情况,这对于 IPv4 是非法的。【参考方案5】:

您可以使用正则表达式,如下所示:

(([0-1]?[0-9]1,2\.)|(2[0-4][0-9]\.)|(25[0-5]\.))3(([0-1]?[0-9]1,2)|(2[0-4][0-9])|(25[0-5]))

这个验证值在范围内。

Android 支持正则表达式。见java.util.regex.Pattern。

class ValidateIPV4


   static private final String IPV4_REGEX = "(([0-1]?[0-9]1,2\\.)|(2[0-4][0-9]\\.)|(25[0-5]\\.))3(([0-1]?[0-9]1,2)|(2[0-4][0-9])|(25[0-5]))";
   static private Pattern IPV4_PATTERN = Pattern.compile(IPV4_REGEX);

   public static boolean isValidIPV4(final String s)
             
      return IPV4_PATTERN.matcher(s).matches();
   

为避免一遍又一遍地重新编译模式,最好调用Pattern.compile() 以便它只执行一次。

【讨论】:

它将匹配“001.xxx.xxx.xxx”。 我不确定,所以发布了一个明确限制0xx, 0x的表达式。 静态私有最终字符串 IPV4_REGEX = "(([0-1]?[0-9]1,2\.)|(2[0-4][0-9]\ .)|(25[0-5]\.))3(([0-1]?[0-9]1,2)|(2[0-4][0-9]) |(25[0-5]))";.这条线给了我错误:( @khachik 有点晚了,但是:那是valid IP address in dotted-decimal notation。事实上,RFC1166实际上在第5页给出了128.009.000.032作为示例。 4个零有效吗? ***.com/questions/25191349/…【参考方案6】:

还有一个未记录的实用程序类sun.net.util.IPAddressUtil,它是you should not actually use,尽管它可能在一个快速的一次性实用程序中很有用:

boolean isIP = IPAddressUtil.isIPv4LiteralAddress(ipAddressString);

在内部,这是 InetAddress 用于解析 IP 地址的实用程序类。

请注意,对于像“123”这样的字符串,这将返回 true,从技术上讲,它是 valid IPv4 addresses,只是不是点十进制表示法。

【讨论】:

【参考方案7】:

The IPAddress Java library 会做到的。链接中提供了 javadoc。免责声明:我是项目经理。

此库透明地支持 IPv4 和 IPv6,因此验证两者的工作方式相同,并且它还支持 CIDR 子网。

验证地址是否有效

    String str = "1.2.3.4";
    IPAddressString addrString = new IPAddressString(str);
    try 
         IPAddress addr = addrString.toAddress();
         ...
     catch(AddressStringException e) 
        //e.getMessage provides validation issue
    

【讨论】:

【参考方案8】:

这是针对 Android 的,正在测试 IPv4IPv6

注意:常用的InetAddressUtils 已弃用。使用新的InetAddress

public static Boolean isIPv4Address(String address) 
    if (address.isEmpty()) 
        return false;
    
    try 
        Object res = InetAddress.getByName(address);
        return res instanceof Inet4Address || res instanceof Inet6Address;
     catch (final UnknownHostException exception) 
        return false;
    

【讨论】:

我不认为这符合作者的要求。如果你传入 InetAddress.getByName("google.com") 你会得到 true,这是因为 getByName 将 dns 名称解析为 IP 地址。【参考方案9】:

编写一个合适的正则表达式并根据它进行验证。 JVM 完全支持正则表达式。

【讨论】:

DVM 也支持吗?我正在使用安卓 好的,我再检查一遍...!!【参考方案10】:

如果是IP4,可以使用正则表达式如下:

^(2[0-5][0-5])|(1\\d\\d)|([1-9]?\\d)\\.)3(2[0-5][0-5])|(1\\d\\d)|([1-9]?\\d)$.

【讨论】:

【参考方案11】:

有很多方法可以实现,但正则表达式更有效。

看下面的代码:

public static void main(String[] args) 

    String ipStr1 = "255.245.188.123"; // valid IP address
    String ipStr2 = "255.245.188.273"; // invalid IP address - 273 is greater than 255

    validateIP(ipStr1);
    validateIP(ipStr2);


public static void validateIP(String ipStr) 
    String regex = "\\b((25[0–5]|2[0–4]\\d|[01]?\\d\\d?)(\\.))3(25[0–5]|2[0–4]\\d|[01]?\\d\\d?)\\b";
    System.out.println(ipStr + " is valid? " + Pattern.matches(regex, ipStr));

【讨论】:

【参考方案12】:

正则表达式是解决这个问题最有效的方法。 看看下面的代码。除了有效性,它还检查它所属的IP地址类别以及它是否是保留的IP地址

Pattern ipPattern;
int[] arr=new int[4];
int i=0;

//Method to check validity
 private String validateIpAddress(String ipAddress) 
      Matcher ipMatcher=ipPattern.matcher(ipAddress);

        //Condition to check input IP format
        if(ipMatcher.matches())        

           //Split input IP Address on basis of .
           String[] octate=ipAddress.split("[.]");     
           for(String x:octate)  

              //Convert String number into integer
              arr[i]=Integer.parseInt(x);             
              i++;
         

        //Check whether input is Class A IP Address or not
         if(arr[0]<=127)                           
             if(arr[0]==0||arr[0]==127)
                 return(" is Reserved IP Address of Class A");
             else if(arr[1]==0&&arr[2]==0&&arr[3]==0)
                 return(" is Class A Network address");
             else if(arr[1]==255&&arr[2]==255&&arr[3]==255)
                 return( " is Class A Broadcast address");
             else 
                 return(" is valid IP Address of Class A");
         

        //Check whether input is Class B IP Address or not
         else if(arr[0]>=128&&arr[0]<=191)         
             if(arr[2]==0&&arr[3]==0)
                 return(" is Class B Network address");
             else if(arr[2]==255&&arr[3]==255)
                 return(" is Class B Broadcast address");
             else
                 return(" is valid IP Address of Class B");
         

        //Check whether input is Class C IP Address or not
         else if(arr[0]>=192&&arr[0]<=223)         
             if(arr[3]==0)
                 return(" is Class C Network address");
             else if(arr[3]==255)
                 return(" is Class C Broadcast address");
             else
                 return( " is valid IP Address of Class C");
        

        //Check whether input is Class D IP Address or not
        else if(arr[0]>=224&&arr[0]<=239)           
             return(" is Class D IP Address Reserved for multicasting");
        

        //Execute if input is Class E IP Address
        else                                     
             return(" is Class E IP Address Reserved for Research and Development by DOD");
        

    

    //Input not matched with IP Address pattern
    else                                     
        return(" is Invalid IP Address");





public static void main(String[] args) 

    Scanner scan= new Scanner(System.in);
    System.out.println("Enter IP Address: ");

    //Input IP Address from user
    String ipAddress=scan.nextLine();  
    scan.close();
    IPAddress obj=new IPAddress();

    //Regex for IP Address
    obj.ipPattern=Pattern.compile("((([0-1]?\\d\\d?|2[0-4]\\d|25[0-5])\\.)3([0-1]?\\d\\d?|2[0-4]\\d|25[0-5]))");

    //Display output
    System.out.println(ipAddress+ obj.validateIpAddress(ipAddress));


【讨论】:

【参考方案13】:

使用正则表达式在两行中获取有效的ip地址请查看代码的评论会话正则表达式如何工作以获取数字范围。

public class regexTest 


    public static void main(String[] args) 
        String IP = "255.001.001.255";
        System.out.println(IP.matches(new MyRegex().pattern));
    

    

    /*
    * /d - stands for any number between 0 to 9
    * /d1,2 - preceding number that 0 to 9 here , can be of 1 digit to 2 digit . so minimum 0 and maximum 99
    * |  this stands for or operator
    *
    * () this is applied on a group to get the single value of outcome
    * (0|1)\d2 = first digit is either 0 or 1 and other two digits can be any number between ( 0 to 9)
    * 2[0-4]\d - first digit is 2 , second digit can be between 0 to 4 and last digit can be 0 to 9
    * 25[0-5] - first two digit will be 25 and last digit will be between 0 to 5
    *
    * */
    class MyRegex 

        String zeroTo255 = "(\\d1,2|(0|1)\\d2|2[0-4]\\d|25[0-5])";
        public String pattern =  zeroTo255 + "\\." + zeroTo255 + "\\." + zeroTo255 + "\\." + zeroTo255;;

    

【讨论】:

【参考方案14】:

请查看 sun.net.util 中的 IPAddressUtil OOTB 类,这应该会对您有所帮助。

【讨论】:

不建议使用sun.*包-> detail【参考方案15】:

如果您不关心范围,以下表达式将有助于验证从 1.1.1.1 到 999.999.999.999

"[1-9]1,3\\.[1-9]1,3\\.[1-9]1,3\\.[1-9]1,3"

【讨论】:

会匹配 10.10.10.10 吗?正则表达式中没有 0【参考方案16】:
public static boolean isIpv4(String ipAddress) 
    if (ipAddress == null) 
        return false;
    
    String ip = "^(1\\d2|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."
            + "(1\\d2|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
            + "(1\\d2|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
            + "(1\\d2|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
    Pattern pattern = Pattern.compile(ip);
    Matcher matcher = pattern.matcher(ipAddress);
    return matcher.matches();

【讨论】:

【参考方案17】:
/**
 * Check if ip is valid
 *
 * @param ip to be checked
 * @return <tt>true</tt> if <tt>ip</tt> is valid, otherwise <tt>false</tt>
 */
private static boolean isValid(String ip) 
    String[] bits = ip.split("\\.");
    if (bits.length != 4) 
        return false;
    
    for (String bit : bits) 
        try 
            if (Integer.valueOf(bit) < 0 || Integer.valueOf(bit) > 255) 
                return false;
            
         catch (NumberFormatException e) 
            return false; /* contains other other character */
        
    
    return true;

【讨论】:

【参考方案18】:

apache-httpcomponents 的库

// ipv4 is true
assertTrue(InetAddressUtils.isIPv4Address("127.0.0.1"));
// not detect the ipv6
assertFalse(InetAddressUtils.isIPv4Address("2001:0db8:85a3:0000:0000:8a2e:0370:7334"));

maven lib(2019 年 9 月更新)

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.10</version>
</dependency>

【讨论】:

【参考方案19】:

我的解决方案(支持前导 0):

   String pattern="^[0-9](\\d1,2|1?[0-9][0-9]|2?[0-4][0-9]|25?[0-5])?\\.(\\d1,2|1?[0-9][0-9]|2?[0-4][0-9]|25[0-5])?\\.(\\d1,2|1?[0-9][0-9]|2?[0-4][0-9]|25[0-5])?\\.(\\d1,2|1?[0-9][0-9]|2?[0-4][0-9]|25[0-5])?$";

【讨论】:

【参考方案20】:
 private static final String IPV4_PATTERN_ALLOW_LEADING_ZERO =
            "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";

【讨论】:

【参考方案21】:
private static boolean findValidIP(String ipAddress) 
        String[] ipAddressSplited = ipAddress.split("\\.");
        int correctFragments = 0;

        for (String ctr : ipAddressSplited) 
            int value = -10;
            try 
                value = Integer.parseInt(ctr);
             catch (NumberFormatException exception) 
                value = -1;
            

            if (value >= 0 && value <= 255 && ipAddressSplited.length == 4) correctFragments++;
        

        System.out.println(correctFragments == 4 ? "Valid IP Address - " + ipAddress : "Invalid IP Address - " + ipAddress);
        return correctFragments == 4;
    

【讨论】:

【参考方案22】:

我编写了一个正则表达式来验证 IPv4。 你可以参考我的解决方案。

import java.util.Scanner;

/**
 * @author ManhKM on 11/26/2021
 * @project java-core-v1.0
 */
public class ValidateIPv4 
    public static void main(String[] args)
        Scanner in = new Scanner(System.in);
        while(in.hasNext())
            String IP = in.next();
            System.out.println(IP.matches(new MyRegex().pattern));
        

    


class MyRegex

    String pattern = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.)3(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";

【讨论】:

【参考方案23】:

public void setIpAddress(String ipAddress) if(ipAddress.matches("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\ .)3(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$")) //正则ipv4 的表达式 这个.ipAddress = ipAddress; 别的 System.out.println("不正确的IP地址");

【讨论】:

嗨。您已多次拒绝并撤消其他用户对您帖子的有用编辑。如果你不喜欢别人为你做格式改进,请自己做。 ***.com/editing-help 以这种无益的格式保留帖子不太可能对您有任何好处。

以上是关于在 Java 中验证 IPv4 地址的主要内容,如果未能解决你的问题,请参考以下文章

Code-Validator:验证网址(可以匹配IPv4地址但没对IPv4地址进行格式验证;IPv6暂时没做匹配)

使用正则表达式验证 IPv4 地址

Code-Validator:验证IPv4地址

用于验证 IPv4 和 IPv6 地址的 Javascript 正则表达式,没有主机名

验证IPv4 IP地址是否有效

使用正则表达式进行 IPv4 验证