468. Validate IP Address
Given a string queryIP, return “IPv4” if IP is a valid IPv4 address, “IPv6” if IP is a valid IPv6 address or “Neither” if IP is not a correct IP of any type.
A valid IPv4 address is an IP in the form “ x 1 . x 2 . x 3 . x 4 x_1.x_2.x_3.x_4 x1.x2.x3.x4” where 0 <= x i x_i xi <= 255 and xi cannot contain leading zeros. For example, “192.168.1.1” and “192.168.1.0” are valid IPv4 addresses while “192.168.01.1”, “192.168.1.00”, and “192.168@1.1” are invalid IPv4 addresses.
A valid IPv6 address is an IP in the form “ x 1 : x 2 : x 3 : x 4 : x 5 : x 6 : x 7 : x 8 x_1:x_2:x_3:x_4:x_5:x_6:x_7:x_8 x1:x2:x3:x4:x5:x6:x7:x8” where:
- 1 <= x i . l e n g t h x_i.length xi.length <= 4
- x i x_i xi is a hexadecimal string which may contain digits, lowercase English letter (‘a’ to ‘f’) and upper-case English letters (‘A’ to ‘F’).
- Leading zeros are allowed in x i x_i xi.
For example, “2001:0db8:85a3:0000:0000:8a2e:0370:7334” and “2001:db8:85a3:0:0:8A2E:0370:7334” are valid IPv6 addresses, while “2001:0db8:85a3::8A2E:037j:7334” and “02001:0db8:85a3:0000:0000:8a2e:0370:7334” are invalid IPv6 addresses.
Example 1:
Input: queryIP = “172.16.254.1”
Output: “IPv4”
Explanation: This is a valid IPv4 address, return “IPv4”.
Example 2:
Input: queryIP = “2001:0db8:85a3:0:0:8A2E:0370:7334”
Output: “IPv6”
Explanation: This is a valid IPv6 address, return “IPv6”.
Example 3:
Input: queryIP = “256.256.256.256”
Output: “Neither”
Explanation: This is neither a IPv4 address nor a IPv6 address.
Constraints:
- queryIP consists only of English letters, digits and the characters ‘.’ and ‘:’.
From: LeetCode
Link: 468. Validate IP Address
Solution:
Ideas:
IPv4 Validation:
- Segment Parsing:
- We manually parse each segment between the dots.
- Check for empty segments or segments longer than 3 digits.
- Ensure no leading zeros unless the segment is zero itself.
- Convert each segment to an integer and check if it’s within the range 0 to 255.
- Delimiter Checks:
- If a dot is at the beginning or if there are two dots in a row, the IP is invalid.
- Ensure that there are exactly 4 segments.
IPv6 Validation:
- Segment Parsing:
- We manually parse each segment between the colons.
- Check for empty segments or segments longer than 4 characters.
- Ensure all characters are valid hexadecimal digits.
- Delimiter Checks:
- If a colon is at the beginning or if there are two colons in a row, the IP is invalid.
- Ensure that there are exactly 8 segments.
General Logic:
- We use manual parsing instead of strtok to accurately detect empty segments and consecutive delimiters.
- After parsing, we return “IPv4” or “IPv6” if the IP address meets all the criteria; otherwise, we return “Neither”.
Code:
char* validIPAddress(char* queryIP) {int len = strlen(queryIP);int i = 0;// Check for IPv4if (strchr(queryIP, '.') != NULL) {int segmentCount = 0;while (i < len) {int segmentLength = 0;int segmentValue = 0;// If we encounter a dot at the start or two dots in a row, it's invalidif (queryIP[i] == '.') {return "Neither";}while (i < len && queryIP[i] != '.') {if (!isdigit(queryIP[i])) {return "Neither";}if (segmentLength == 0 && queryIP[i] == '0' && (i + 1 < len && queryIP[i + 1] != '.')) {return "Neither"; // Leading zero}segmentValue = segmentValue * 10 + (queryIP[i] - '0');if (segmentValue > 255) {return "Neither";}segmentLength++;i++;}if (segmentLength == 0 || segmentLength > 3) {return "Neither";}segmentCount++;if (segmentCount > 4) {return "Neither";}if (i < len && queryIP[i] == '.') {i++; // Skip the dot// Check for double dotsif (i >= len || queryIP[i] == '.') {return "Neither";}}}return segmentCount == 4 ? "IPv4" : "Neither";}// Check for IPv6else if (strchr(queryIP, ':') != NULL) {int segmentCount = 0;while (i < len) {int segmentLength = 0;// If we encounter a colon at the start or two colons in a row, it's invalidif (queryIP[i] == ':') {return "Neither";}while (i < len && queryIP[i] != ':') {if (!isxdigit(queryIP[i])) {return "Neither";}segmentLength++;if (segmentLength > 4) {return "Neither";}i++;}if (segmentLength == 0) {return "Neither";}segmentCount++;if (segmentCount > 8) {return "Neither";}if (i < len && queryIP[i] == ':') {i++; // Skip the colon// Check for double colonsif (i >= len || queryIP[i] == ':') {return "Neither";}}}return segmentCount == 8 ? "IPv6" : "Neither";}return "Neither";
}