it-swarm.com.de

Überprüfung der IPv4-Zeichenfolge in Java

Die unten angegebene Methode überprüft, ob string eine korrekte IPv4-Adresse ist, und gibt true zurück, wenn sie gültig ist. Jede Verbesserung der Regex und Eleganz wäre sehr zu begrüßen: 

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;
    }
}
43
Mat B.

Hier ist ein einfach zu lesender, etwas weniger effizienter Weg, wie Sie es tun könnten.

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;
    }
}
50
rouble

UPDATE: Commons-HttpClient und sein Nachfolger HttpComponents-HttpClient haben diese Funktionalität übernommen. Sie können diese Version wie folgt verwenden: InetAddressUtils.isIPv4Address(Str).


Die Entwicklungsversion von Apache Commons Validator hat eine InetAddressValidator -Klasse, die über eine isValidInet4Address(String) - Methode verfügt, um zu überprüfen, ob eine gegebene String eine gültige IPv4-Adresse ist.

Der Quellcode kann vom Repository aus betrachtet werden, so dass einige Verbesserungsvorschläge möglich sind, falls Sie das Gefühl haben, dass es welche gibt.

Ein kurzer Blick auf den bereitgestellten Code zeigt, dass Ihre Methode bei jedem Aufruf der Methode eine Pattern kompiliert. Ich würde diese Pattern-Klasse in ein static-Feld verschieben, um den kostspieligen Muster-Kompilierungsprozess bei jedem Aufruf zu vermeiden.

44
coobird

Wenn Sie eine Bibliothek mit einer freigegebenen Version verwenden möchten, die Unterstützung für IPv4 und IPv6 bietet, können Sie Guava verwenden. 

boolean isValid = InetAddresses.isInetAddress("1.2.3.4");
20
Stefan L

Hier ist eine Lösung, die Java 8-Streams verwendet, um zu überprüfen, dass die Adresse aus genau 4 Zahlen zwischen 0 und 255 besteht, die durch Punkte getrennt sind:

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]
    }
}
15
Raniz

Wenn es Ihnen nichts ausmacht, die DNS-Auflösung für ungültige IP-Adressen wie www.example.com zu verwenden, können Sie die Methoden InetAddress verwenden, um Folgendes zu überprüfen: 

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;
}

Die Methode prüft, ob es sich um eine Instanz von Inet4Address handelt und ob der Parameter die IP-Adresse und nicht der Hostname war. Wenn Sie viele Hostnamen als Parameter erwarten, beachten Sie, dass diese Implementierung DNS verwendet, um zu versuchen, ihn aufzulösen. Dies könnte ein Leistungsproblem sein. 

Andernfalls können Sie in boolean Sun.net.util.IPAddressUtil.isIPv4LiteralAddress(String src) einen Spitzenwert angeben, wie der String dort für die IPv4-Überprüfung analysiert wird.

14

Regex-Beispiel aus this finden

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();             
    }
}
7
bigspawn

Diese Lösung ist meiner Meinung nach ziemlich elegant, obwohl es eine Minute dauert, um sie zu verstehen.

Die Grundidee ist, eine Unterzeichenfolge zu nehmen und sie dann zu überprüfen.
Bitte beachten Sie, dass ich zwischen x und y umschalte, da der Anfang einer Unterzeichenfolge immer das Ende der letzten Zeichenfolge plus 1 ist. 

Diese Lösung ist ca. 20x schneller als eine Regex-Variante und 2x schneller als das Aufteilen.

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;
    }
}

Wenn Sie wissen, dass Sie viele falsche IPs haben, sollten Sie den folgenden Code unter dem ersten hinzufügen, wenn. Dadurch wird der Code um das 1,5-fache verlangsamt, im Fehlerfall jedoch um das 700-fache verbessert

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

Wenn Sie den Code in der Frage verwenden, müssen Sie die Zeile ändern:

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

zu 

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

Die meisten Antworten (außer die von Michael Konietzka) sind falsch: 10.8 ist zum Beispiel eine gültige IP4-Adresse (eine Abkürzung für 10.0.0.8).

Siehe Textuelle Darstellung von IP-Adressen in den Java-Spezifikationen.

Wie aus der Literaturstelle hervorgeht, können zur Überprüfung einer numerischen Darstellung 1 bis 4 Teile vorhanden sein, und es gelten jeweils unterschiedliche Einschränkungen für die Teile.

3

Versuchen Sie, den folgenden Regex für IPv4 zu verwenden

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}$";

ich hoffe es hilft :)

3
bane19

Ich denke, der beste Weg ist, eine IPAddress-Klasse zu erstellen und sie instanziieren, indem sie der IP-Adresse eine Zeichenfolgendarstellung gibt.

Auf diese Weise können Sie die verschiedenen Validierungsschritte in Instanzmethoden aufteilen und Trennung von Anliegen in Gang setzen.

Zum Beispiel handelt es sich hier normalerweise um eine eigene Methode, nennen Sie dies einfach isEmpty:

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

Auch dies sollte eine separate Methode sein, Sie könnten diese hasProbableLength nennen.

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

Hier ist viel los. Ich würde versuchen, das zu unterbrechen und vielleicht den Regex vollständig auszulassen.

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;
}

Ich würde zuerst die Saite in Punkte aufteilen und sehen, dass ich genau vier Gruppen bekomme. Rufen Sie diese Methode auf divideIntoGroups

Ich würde dann jede der Gruppen für einen Wert zwischen 0 und 255 validieren. Rufen Sie diese Methode auf validateGroups

Wenn Sie nun diese Klasse erweitern möchten, um auch nach IP-Adressen von localhost oder Broadcast-Adressen zu suchen, ist dies ziemlich einfach. Dies ist, was Trennung von Anliegen gibt.

Sie können auch genau feststellen, welche Ihrer Validierungsregeln bei der Validierung der IP-Adresszeichenfolge verletzt wurde. Etwas, das Regex nicht tut.

3
firelynx

Die einfachste Möglichkeit, zu überprüfen, ob ip in ipv4 richtig ist, ist die Verwendung von commons-validator-1.4.0.jar mit der Klasse: - 

org.Apache.commons.validator.routines.InetAddressValidator

InetAddressValidator

Z.B. 

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

die diese einfache Regex verwendet: -

  "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$";
2
boolean isValid = inetAddressValidator.isValid(hostName) || hostName.equalsIgnoreCase("localhost");

gleiche Antwort wie Coobird. Fügen Sie einfach localhost zur Anweisung hinzu. Die meisten Umgebungen verwenden 'localhost' als gültigen Hostnamen. Es handelt sich nicht um ein IPV4-Format, es sollte jedoch zur Gültigkeit berücksichtigt werden.

1
rinjan

Die IPAddress Java-Bibliothek wird es tun. Der Javadoc ist unter dem Link verfügbar. Haftungsausschluss: Ich bin der Projektmanager.

Diese Bibliothek unterstützt transparent IPv4 und IPv6, sodass die Überprüfung entweder wie folgt funktioniert und auch IPC4-Adressen mit CIDR-Präfixlänge unterstützt. Es unterstützt die ungewöhnlicheren Formate wie inet_aton (in einer anderen Antwort wurde beispielsweise 10.8 erwähnt)

Überprüfen Sie, ob eine Adresse gültig ist:

    String str = "1.2.3.4";
    IPAddressString addrString = new IPAddressString(str);
    try {
         IPAddress addr = addrString.toAddress();
         ...
    } catch(AddressStringException e) {
        //e.getMessage provides validation issue
    }
1
Sean F
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;
    }       
}
1
user7839057

Ich würde vorschlagen, das zu verwenden, was auf der Plattform/dem Framework, das Sie entwickeln, verfügbar ist.

Wenn es nichts gibt, was Sie für gut genug halten, möchten Sie vielleicht nur eine kompilierte Regex zu einer Hilfsklasse hinzufügen. Zum Beispiel hier wie es das Android-Framework macht:

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]))");
1