468. Validate IP Address

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
class Solution {
public String validIPAddress(String queryIP) {
if (isIPv4(queryIP)) {
return "IPv4";
} else if (isIPv6(queryIP)) {
return "IPv6";
} else {
return "Neither";
}
}

private boolean isIPv4(String queryIP) {
String[] strs = queryIP.split("\\.", -1);
if (strs.length != 4) {
return false;
}
for (String str : strs) {
if (str.isEmpty() || (str.charAt(0) == '0' && str.length() > 1) || str.length() > 3) { // 此处的长度限制能够避免后续转换数字时越界
return false;
}
int num = 0;
for (int i = 0; i < str.length(); i++) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
num = num * 10 + (str.charAt(i) - '0');
}
if (num > 255) {
return false;
}
}

return true;
}

private boolean isIPv6(String queryIP) {
String[] strs = queryIP.split(":", -1);
if (strs.length != 8) {
return false;
}
for (String str : strs) {
if (str.isEmpty() || str.length() > 4) {
return false;
}
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (!isHexChar(c)) {
return false;
}
}
}

return true;
}

private boolean isHexChar(char c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
}

注意单个参数的 String#split 方法默认未包含末尾的空字符串,若需要包含末尾的空字符串,则需要显式指定第二个参数为负数。

References

468. Validate IP Address
Why does “split” on an empty string return a non-empty array?