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

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

【问题讨论】:

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

标签: java ip-address


【解决方案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】:

【讨论】:

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

使用Guava

InetAddresses.isInetAddress(ipStr)

【讨论】:

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

请参阅https://stackoverflow.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作为示例。
【解决方案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
                * /d{1,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)\d{2} = 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 = "(\\d{1,2}|(0|1)\\d{2}|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\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."
                          + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
                          + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
                          + "(1\\d{2}|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](\\d{1,2}|1?[0-9][0-9]|2?[0-4][0-9]|25?[0-5])?\\.(\\d{1,2}|1?[0-9][0-9]|2?[0-4][0-9]|25[0-5])?\\.(\\d{1,2}|1?[0-9][0-9]|2?[0-4][0-9]|25[0-5])?\\.(\\d{1,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地址"); }

                            【讨论】:

                            • 嗨。您已多次拒绝并撤消其他用户对您帖子的有用编辑。如果你不喜欢别人为你做格式改进,请自己做。 stackoverflow.com/editing-help 以这种无益的格式保留帖子不太可能对您有任何好处。
                            猜你喜欢
                            • 1970-01-01
                            • 2023-04-01
                            • 2017-04-16
                            • 2011-07-14
                            • 2011-06-02
                            • 1970-01-01
                            • 2012-10-30
                            • 2012-01-03
                            相关资源
                            最近更新 更多