4

How can I check if a string matches a IPv4, IPv6 adress or a domain name like www.google.com?

I found this for IPv4: Validating IPv4 string in Java And the same kind of system works for IPv6 but how can I check domain names?

EDIT: To clarify: I want to check if a string is a valid server address. Valid just means that the FORMAT is correct. The connection will be testet at a different point in the program.

F_Schmidt
  • 902
  • 1
  • 11
  • 32
  • 1
    Do you want to *validate* it is IPv6, or *distinguish* between IPv4 and IPv6 and domain when you already know it's one or the other? – Bohemian Apr 02 '20 at 21:18

4 Answers4

3

While it is true there are a lot of corner cases, this is straightforward with The IPAddress Java library. I advise against using regular expressions, there are too many variations. Disclaimer: I am the project manager of the IPAddress library.

Here is sample code:

check("1.2.3.4");
check("1.2.a.4");
check("::1");
check("[::1]");
check("1.2.?.4");  

static void check(String hostStr) {
   HostName host = new HostName(hostStr);
   try {
       host.validate();
       if(host.isAddress()) {
           IPAddress addr = host.asAddress();
           System.out.println(addr.getIPVersion() + " address: " + addr);
       } else {
           System.out.println("host name: " + host);
       }
   } catch(HostNameException e) {
       System.out.println(e.getMessage());
   }
}

Output:

IPv4 address: 1.2.3.4
host name: 1.2.a.4
IPv6 address: ::1
IPv6 address: ::1
1.2.?.4 Host error: invalid character at index 4
Sean F
  • 4,344
  • 16
  • 30
2

Apache has domain name validation:

 public void testValidDomains() {
        assertTrue("apache.org should validate", validator.isValid("apache.org"));
        assertTrue("www.google.com should validate", validator.isValid("www.google.com"));

        assertTrue("test-domain.com should validate", validator.isValid("test-domain.com"));
        assertTrue("test---domain.com should validate", validator.isValid("test---domain.com"));
        assertTrue("test-d-o-m-ain.com should validate", validator.isValid("test-d-o-m-ain.com"));
        assertTrue("two-letter domain label should validate", validator.isValid("as.uk"));

        assertTrue("case-insensitive ApAchE.Org should validate", validator.isValid("ApAchE.Org"));

        assertTrue("single-character domain label should validate", validator.isValid("z.com"));

        assertTrue("i.have.an-example.domain.name should validate", validator.isValid("i.have.an-example.domain.name"));
    }

    public void testInvalidDomains() {
        assertFalse("bare TLD .org shouldn't validate", validator.isValid(".org"));
        assertFalse("domain name with spaces shouldn't validate", validator.isValid(" apache.org "));
        assertFalse("domain name containing spaces shouldn't validate", validator.isValid("apa che.org"));
        assertFalse("domain name starting with dash shouldn't validate", validator.isValid("-testdomain.name"));
        assertFalse("domain name ending with dash shouldn't validate", validator.isValid("testdomain-.name"));
        assertFalse("domain name starting with multiple dashes shouldn't validate", validator.isValid("---c.com"));
        assertFalse("domain name ending with multiple dashes shouldn't validate", validator.isValid("c--.com"));
        assertFalse("domain name with invalid TLD shouldn't validate", validator.isValid("apache.rog"));

        assertFalse("URL shouldn't validate", validator.isValid("http://www.apache.org"));
        assertFalse("Empty string shouldn't validate as domain name", validator.isValid(" "));
        assertFalse("Null shouldn't validate as domain name", validator.isValid(null));
    }

Hope that helps.

hd1
  • 33,938
  • 5
  • 80
  • 91
  • Thank you! I will not use the apache method, but the unit test is nice! I will use it to validate my own method! – F_Schmidt Apr 02 '20 at 21:32
1

You do it with regular expressions. You can create a pattern where the first 3 characters are 'w', then a dot, then for example 20 alphanumeric charcacters and so on. After that you check if the given string matches the defined pattern.

The link you provided already uses regular expressions.

Checkout this tutorial on regex in java.

Paul Erlenmeyer
  • 523
  • 2
  • 6
  • 29
  • Okay, I thought that was the way to go, thanks for the link! – F_Schmidt Apr 02 '20 at 21:33
  • 1
    `Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.` - https://en.wikiquote.org/wiki/Jamie_Zawinski ;) – jannis Apr 02 '20 at 21:36
-1

Don't bother. There's just too many corner cases and in the end there's still a big chance that connection test will fail. You'll also end up with a lot of false-negative validations.

Just move connection testing closer to the place this domain/ip gets into the system.

jannis
  • 4,843
  • 1
  • 23
  • 53
  • But sometimes you need it. Suppose this IP address comes from "Internet User Eve" and you are going to insert it into a string that will become in URI somewhere later. False-negatives validations are quite acceptable. – David Tonhofer May 09 '21 at 10:31