## 468. Validate IP Address

Write a function to check whether an input string is a valid IPv4 address or IPv6 address or neither.

IPv4 addresses are canonically represented in dot-decimal notation, which consists of four decimal numbers, each ranging from 0 to 255, separated by dots ("."), e.g.,`172.16.254.1`;

Besides, leading zeros in the IPv4 is invalid. For example, the address`172.16.254.01`is invalid.

IPv6 addresses are represented as eight groups of four hexadecimal digits, each group representing 16 bits. The groups are separated by colons (":"). For example, the address`2001:0db8:85a3:0000:0000:8a2e:0370:7334`is a valid one. Also, we could omit some leading zeros among four hexadecimal digits and some low-case characters in the address to upper-case ones, so`2001:db8:85a3:0:0:8A2E:0370:7334`is also a valid IPv6 address(Omit leading zeros and using upper cases).

However, we don't replace a consecutive group of zero value with a single empty group using two consecutive colons (::) to pursue simplicity. For example,`2001:0db8:85a3::8A2E:0370:7334`is an invalid IPv6 address.

Besides, extra leading zeros in the IPv6 is also invalid. For example, the address`02001:0db8:85a3:0000:0000:8a2e:0370:7334`is invalid.

Note:You may assume there is no extra space or special characters in the input string.

Example 1:

``````Input: "172.16.254.1"

Output: "IPv4"

Explanation: This is a valid IPv4 address, return "IPv4".
``````

Example 2:

``````Input: "2001:0db8:85a3:0:0:8A2E:0370:7334"

Output: "IPv6"

Explanation: This is a valid IPv6 address, return "IPv6".
``````

Example 3:

``````Input: "256.256.256.256"

Output: "Neither"

Explanation: This is neither a IPv4 address nor a IPv6 address.
``````

Code: Java Regex

``````public class Solution {
public String validIPAddress(String IP) {
if(IP.matches("(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"))return "IPv4";
if(IP.matches("(([0-9a-fA-F]{1,4}):){7}([0-9a-fA-F]{1,4})"))return "IPv6";
return "Neither";
}
}
``````

Python: using int

``````class Solution(object):

def isIPv4(s):
try: return str(int(s)) == s and 0 <= int(s) <= 255 #  str(int(s)) == s enforces to drop the leading 0's and all numbers a non-characters
except: return False

def isIPv6(s):
if len(s) > 4 : return False # only allows less that 4
try: return int(s, 16) >= 0 and s != '-' and s != '+' # to prevent int to conver +xxx or -xxx
except: return False

if IP.count(".") == 3 and all(isIPv4(i) for i in IP.split(".")):
return "IPv4"
if IP.count(":") == 7 and all(isIPv6(i) for i in IP.split(":")):
return "IPv6"
return "Neither"
``````

C++ Normal

``````class Solution {
public:
const string validIPv6Chars = "0123456789abcdefABCDEF";
const string digits = "0123456789";
bool isValidIPv4Block(string& block) {
int num = 0;
//check length
if (block.size() > 0 && block.size() <= 3) {
for (int i = 0; i < block.size(); i++) {
char c = block[i];
// check value
if (digits.find(c)== string::npos || (i == 0 && c == '0' && block.size() > 1))  // special case: if c is a leading zero
return false;
else {
num *= 10;
num += c - '0';
}
}
return num <= 255;
}
return false;
}

bool isValidIPv6Block(string& block) {
//check length
if (block.size() > 0 && block.size() <= 4) {
for (int i = 0; i < block.size(); i++) {
char c = block[i];
// check value
if (validIPv6Chars.find(c) == string::npos)
return false;
}
return true;
}
return false;
}

string validIPAddress(string IP) {
stringstream ss(IP);
string block;
// ipv4 candidate
if (IP.substr(0, 4).find('.') != string::npos) {
for (int i = 0; i < 4; i++) {
if (!getline(ss, block, '.') || !isValidIPv4Block(block))
return "Neither";
}
return ss.eof() ? "IPv4" : "Neither";
}
// ipv6 candidate
else if (IP.substr(0, 5).find(':') != string::npos) {
for (int i = 0; i < 8; i++) {
if (!getline(ss, block, ':') || !isValidIPv6Block(block))
return "Neither";
}
return ss.eof() ? "IPv6" : "Neither";
}

return "Neither";
}
};
``````