在Java中验证IPv4字符串

时间:2011-01-03 03:26:40

标签: java string validation ip

Bellow方法验证字符串是否正确IPv4地址如果有效则返回true。正如此,正则表达式和优雅的任何改进都将非常受欢迎:

public static boolean validIP(String ip) {
    if (ip == null || ip.isEmpty()) return false;
    ip = ip.trim();
    if ((ip.length() < 6) & (ip.length() > 15)) return false;

    try {
        Pattern pattern = Pattern.compile("^(?:(?: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]?)$");
        Matcher matcher = pattern.matcher(ip);
        return matcher.matches();
    } catch (PatternSyntaxException ex) {
        return false;
    }
}

17 个答案:

答案 0 :(得分:52)

这是一种更容易阅读,效率稍低的方式。

public static boolean validIP (String ip) {
    try {
        if ( ip == null || ip.isEmpty() ) {
            return false;
        }

        String[] parts = ip.split( "\\." );
        if ( parts.length != 4 ) {
            return false;
        }

        for ( String s : parts ) {
            int i = Integer.parseInt( s );
            if ( (i < 0) || (i > 255) ) {
                return false;
            }
        }
        if ( ip.endsWith(".") ) {
            return false;
        }

        return true;
    } catch (NumberFormatException nfe) {
        return false;
    }
}

答案 1 :(得分:45)

UPDATE: Commons-HttpClient及其后继者HttpComponents-HttpClient已采用此功能。您可以像这样使用此版本:InetAddressUtils.isIPv4Address(Str)


Apache Commons Validator的开发版本有一个InetAddressValidator类,其中有一个isValidInet4Address(String)方法可以检查给定的String是否为有效的IPv4地址。< / p>

可以从存储库中查看source code,这样如果您觉得有任何改进,可能会提供一些改进的想法。

快速浏览一下提供的代码,可以看出您的方法是在每次调用方法时编译Pattern。我会将Pattern类移到static字段,以避免每次调用都进行昂贵的模式编译过程。

答案 2 :(得分:21)

如果要使用具有支持IPv4和IPv6支持的已发布版本的库,可以使用Guava

boolean isValid = InetAddresses.isInetAddress("1.2.3.4");

答案 3 :(得分:15)

这是一个使用Java 8流来检查地址是否包含0到255之间的4个数字的解决方案,以点分隔:

public class IpValidation {

    /**
     * Check that a string represents a decimal number
     * @param string The string to check
     * @return true if string consists of only numbers without leading zeroes, false otherwise
     */
    public static boolean isDecimal(String string) {
        if (string.startsWith("0")) {
            if (string.length() == 1) {
                 // "0"
                 return true;
            }
            // The string has a leading zero but is not "0"
            return false;
        }
        for(char c : string.toCharArray()) {
            if(c < '0' || c > '9') {
                return false;
            }
        }
        return true;
    }

    public static boolean isIp(String string) {
        String[] parts = string.split("\\.", -1);
        return parts.length == 4 // 4 parts
                && Arrays.stream(parts)
                .filter(IpValidation::isDecimal) // Only decimal numbers
                .map(Integer::parseInt)
                .filter(i -> i <= 255 && i >= 0) // Must be inside [0, 255]
                .count() == 4; // 4 numerical parts inside [0, 255]
    }
}

答案 4 :(得分:14)

如果您不介意在www.example.com这样的无效IP地址上使用DNS解析,则可以使用InetAddress方法进行检查:

public static final boolean checkIPv4(final String ip) {
    boolean isIPv4;
    try {
    final InetAddress inet = InetAddress.getByName(ip);
    isIPv4 = inet.getHostAddress().equals(ip)
            && inet instanceof Inet4Address;
    } catch (final UnknownHostException e) {
    isIPv4 = false;
    }
    return isIPv4;
}

该方法检查它是否是Inet4Address的实例,如果参数是ip-address而不是主机名。 如果您希望将大量主机名作为参数,请注意此实现使用DNS尝试解析它。这可能是一个性能问题。

否则你可以有一个高峰 boolean sun.net.util.IPAddressUtil.isIPv4LiteralAddress(String src)如何在那里解析String以进行IPv4检查。

答案 5 :(得分:7)

this

中查找正则表达式示例
package com.mkyong.regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class IPAddressValidator{

    private Pattern pattern;
    private Matcher matcher;

    private static final String IPADDRESS_PATTERN = 
        "^([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])$";

    public IPAddressValidator(){
      pattern = Pattern.compile(IPADDRESS_PATTERN);
    }

   /**
    * Validate ip address with regular expression
    * @param ip ip address for validation
    * @return true valid ip address, false invalid ip address
    */
    public boolean validate(final String ip){         
      matcher = pattern.matcher(ip);
      return matcher.matches();             
    }
}

答案 6 :(得分:5)

认为这个解决方案非常优雅,虽然需要花一点时间来理解它。

基本的想法是取一个子串而不是验证它。
请注意我切换x和y,因为子串的开头总是最后一个加1的结束。

此解决方案比正则表达式变体快约20倍,比分割快2倍。

public static boolean validIP(String ip) {
    if(ip == null || ip.length() < 7 || ip.length() > 15) return false;

    try {
        int x = 0;
        int y = ip.indexOf('.');

        if (y == -1 || ip.charAt(x) == '-' || Integer.parseInt(ip.substring(x, y)) > 255) return false;

        x = ip.indexOf('.', ++y);
        if (x == -1 || ip.charAt(y) == '-' || Integer.parseInt(ip.substring(y, x)) > 255) return false;

        y = ip.indexOf('.', ++x);
        return  !(y == -1 ||
                ip.charAt(x) == '-' ||
                Integer.parseInt(ip.substring(x, y)) > 255 ||
                ip.charAt(++y) == '-' ||
                Integer.parseInt(ip.substring(y, ip.length())) > 255 ||
                ip.charAt(ip.length()-1) == '.');

    } catch (NumberFormatException e) {
        return false;
    }
}

如果您知道您有很多错误的IP,请考虑在第一个if下面添加以下代码。这将使代码慢1.5倍但如果出现错误则将其提高700倍

    for (int i = 0; i < ip.length(); i++) {
        if (!Character.isDigit(ip.charAt(i)) && ip.charAt(i) != '.') return false;
    }

答案 7 :(得分:4)

如果您使用问题中的代码,则需要更改行:

if ((ip.length() < 6) & (ip.length() > 15)) return false;

if ((ip.length() <= 6) || (ip.length() > 15)) return false;

答案 8 :(得分:4)

大多数答案(Michael Konietzka除外)都是错误的:例如,10.8是一个有效的IP4地址(10.0.0.8的简写)。

请参阅Java规范中的Textual representation of IP addresses

从参考文献中可以看出,为了检查数字表示,可能有1到4个部分,并且在每种情况下对部件的不同限制都适用。

答案 9 :(得分:3)

尝试使用以下regrex for IPv4

String ip4Regex="^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})(\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})){3}$";

希望它有所帮助:)

答案 10 :(得分:3)

我认为正确的方法是构建一个IPAddress类,并通过给它一个ip地址的字符串表示来实现它。

通过这种方式,您可以将不同的验证步骤拆分为实例方法,并获得一些separation of concern

例如,这里通常是它自己的方法,只需调用它isEmpty

return (ip == null || ip.isEmpty());

此外,这应该是一个单独的方法,您可以将其称为hasProbableLength

ip = ip.trim();
return ((ip.length() < 6) & (ip.length() > 15));

这里有很多事情要发生。我会尝试打破这一点,也许会尝试完全跳过正则表达式。

try {
    Pattern pattern = Pattern.compile("^(?:(?: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]?)$");
    Matcher matcher = pattern.matcher(ip);
    return matcher.matches();
} catch (PatternSyntaxException ex) {
    return false;
}

我首先将字符串分成点,然后看到我恰好有四组。请调用此方法divideIntoGroups

然后我会验证每个组是否为0到255之间的值。调用此方法validateGroups

现在您已经拥有了这个,如果您想扩展此类以查找IP是localhost还是广播地址,那么这很容易实现。这是separation of concerns给你的。

您还可以确切地确定验证IP地址字符串中的哪一个验证规则已被破坏。正则表达式不会的东西。

答案 11 :(得分:2)

我发现在ipv4中正确检查给定ip的最简单的方法是使用commons-validator-1.4.0.jar有类: -

org.apache.commons.validator.routines.InetAddressValidator

InetAddressValidator

E.g。

InetAddressValidator inetValidator = InetAddressValidator.getInstance();
inetValidator.isValidInet4Address(yourIPAddress);

使用这个简单的正则表达式: -

  "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$";

答案 12 :(得分:1)

我建议您使用您正在开发的平台/框架上提供的内容。

如果您认为没有什么是好的,那么您可能只想将编译的正则表达式添加到帮助程序类中。例如,here&#39} Android框架是如何做到的:

public static final Pattern IP_ADDRESS
    = Pattern.compile(
        "((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]"
        + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
        + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
        + "|[1-9][0-9]|[0-9]))");

答案 13 :(得分:1)

boolean isValid = inetAddressValidator.isValid(hostName) || hostName.equalsIgnoreCase("localhost");
与coobird相同的答案。只需将localhost添加到语句中即可。大多数环境将“localhost”作为有效的主机名。它不是ipv4格式,但应包括在内以考虑有效性。

答案 14 :(得分:1)

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

该库透明地支持IPv4和IPv6,因此验证在下面的工作方式相同,并且它也支持CIDR前缀长度的IPC4地址。它支持更不寻常的格式,如inet_aton(例如10.8在另一个答案中提到)

验证地址是否有效:

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

答案 15 :(得分:1)

public static boolean ipv4Check(String ipAddress){

    try{
        if(ipAddress!=null && !ipAddress.isEmpty()){
            String [] ip = ipAddress.split("\\.");
            if(ip.length!=4)
                return false;

            for(int i=0;i<=ip.length-1;i++){
                int j=Integer.parseInt(ip[i]);
                if(j<0 || j>255){
                    return false;
                }
            }
            if ( ipAddress.endsWith(".") ) {
                return false;
            }
            if ( ipAddress.startsWith(".") ) {
                return false;
            }

        }
        return true;
    } catch (NumberFormatException ex) {
        return false;
    }       
}

答案 16 :(得分:1)

对你有用,


boolean isIPv4Address(String inputString) {
    String[] splitString = inputString.split("[.]");
    if (splitString.length > 4) {
        return false;
    }
    for (String string : splitString) {
        if (string.isEmpty()) {
            return false;
        }
        if (!string.matches("[0-9]{1,3}")) {
            return false;
        }
        int number = Integer.parseInt(string);
        if (!(number >= 0 && number <= 255)) {
            return false;
        }
    }
    return true;
}