Validate IP Address
Problem statement
Given a string queryIP, return "IPv4" if it is a valid IPv4 address, "IPv6" if it is a valid IPv6 address, and "Neither" otherwise. Use these rules:
- IPv4: exactly four parts separated by
.. Each part is 1 to 3 decimal digits with a value from 0 to 255, and has no leading zero unless the part is exactly0. So10.0.1.15is valid, while10.0.01.15and10.0.1.256are not. - IPv6: exactly eight groups separated by
:. Each group is 1 to 4 hexadecimal digits (0-9,a-f,A-F). Leading zeros are allowed. The shortened::form is not accepted here.
Nothing else may appear in the string: no spaces, no signs, no empty parts.
Examples
Example 1
Input: queryIP = "10.0.1.15"
Output: "IPv4"
Example 2
Input: queryIP = "fd00:1a2b:0:0:0:0:ff:9"
Output: "IPv6"
Explanation: Eight groups, each 1 to 4 hex digits. Case and leading zeros don't matter for IPv6.
Hints
Approach
Split and check each part by hand.
- If the string contains a
., split on.and require exactly 4 parts. Each part must be 1 to 3 characters, all in0-9, must not start with0unless it is exactly"0", and must be at most 255. - Otherwise, if it contains a
:, split on:and require exactly 8 parts. Each must be 1 to 4 characters, all hexadecimal digits. - Anything else is
"Neither".
In Java, call split(regex, -1). Without the -1, Java silently drops trailing empty strings, so "1.2.3.4." would split into four parts and wrongly pass.
O(n)Space O(n)class Solution: def validIPAddress(self, queryIP: str) -> str: if "." in queryIP and self._is_v4(queryIP): return "IPv4" if ":" in queryIP and self._is_v6(queryIP): return "IPv6" return "Neither" def _is_v4(self, ip: str) -> bool: parts = ip.split(".") if len(parts) != 4: return False for p in parts: if not 1 <= len(p) <= 3 or any(c not in "0123456789" for c in p): return False if len(p) > 1 and p[0] == "0": # no leading zeros return False if int(p) > 255: return False return True def _is_v6(self, ip: str) -> bool: hexdigits = set("0123456789abcdefABCDEF") parts = ip.split(":") if len(parts) != 8: return False return all(1 <= len(p) <= 4 and all(c in hexdigits for c in p) for p in parts)Follow-up questions
- Accept the compressed IPv6 form with
::and expand it to eight groups. - Validate CIDR notation such as
10.0.0.0/16, and check whether an address falls inside it.
Frequently asked questions
They follow the real standards, which differ from this problem's rules: real IPv6 allows the :: shorthand, and InetAddress.getByName may try a DNS lookup for anything that isn't a literal. In production code, prefer the library; in the interview, the point is writing the validation yourself.
Some parsers read a part like 010 as octal (8), so 10.0.010.1 can mean different addresses to different tools. Rejecting leading zeros removes that ambiguity.
Validating addresses from config files, API input or firewall rules is routine for network, SRE and platform engineers. The question checks careful parsing: exact part counts, empty parts, ranges and character sets.