|
1 | 1 | package com.fishercoder.solutions;
|
2 | 2 |
|
| 3 | +import java.util.Arrays; |
| 4 | +import java.util.HashSet; |
| 5 | +import java.util.Set; |
| 6 | + |
3 | 7 | /**
|
| 8 | + * 468. Validate IP Address |
4 | 9 | * Write a function to check whether an input string is a valid IPv4 address or IPv6 address or neither.
|
5 |
| -
|
6 |
| - 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; |
7 |
| -
|
| 10 | + IPv4 addresses are canonically represented in dot-decimal notation, which consists of four decimal numbers, |
| 11 | + each ranging from 0 to 255, separated by dots ("."), e.g.,172.16.254.1; |
8 | 12 | Besides, leading zeros in the IPv4 is invalid. For example, the address 172.16.254.01 is invalid.
|
9 | 13 |
|
10 |
| - 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). |
| 14 | + IPv6 addresses are represented as eight groups of four hexadecimal digits, |
| 15 | + each group representing 16 bits. |
| 16 | + The groups are separated by colons (":"). |
| 17 | + For example, the address 2001:0db8:85a3:0000:0000:8a2e:0370:7334 is a valid one. |
| 18 | + Also, we could omit some leading zeros among four hexadecimal digits and |
| 19 | + some low-case characters in the address to upper-case ones, |
| 20 | + so 2001:db8:85a3:0:0:8A2E:0370:7334 is also a valid IPv6 address(Omit leading zeros and using upper cases). |
11 | 21 |
|
12 |
| - 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. |
| 22 | + However, we don't replace a consecutive group of zero value with a single empty |
| 23 | + group using two consecutive colons (::) to pursue simplicity. |
| 24 | + For example, 2001:0db8:85a3::8A2E:0370:7334 is an invalid IPv6 address. |
13 | 25 |
|
14 |
| - Besides, extra leading zeros in the IPv6 is also invalid. For example, the address 02001:0db8:85a3:0000:0000:8a2e:0370:7334 is invalid. |
| 26 | + Besides, extra leading zeros in the IPv6 is also invalid. |
| 27 | + For example, the address 02001:0db8:85a3:0000:0000:8a2e:0370:7334 is invalid. |
15 | 28 |
|
16 | 29 | Note: You may assume there is no extra space or special characters in the input string.
|
17 | 30 |
|
|
42 | 55 | */
|
43 | 56 | public class _468 {
|
44 | 57 |
|
| 58 | + static final String NEITHER = "Neither"; |
45 | 59 | public String validIPAddress(String IP) {
|
46 |
| - String[] bytes = IP.split("."); |
47 |
| - return ""; |
| 60 | + if (IP.contains(".")) { |
| 61 | + return isValidIPv4(IP); |
| 62 | + } else if (IP.contains(":")) { |
| 63 | + return isValidIPv6(IP); |
| 64 | + } else return NEITHER; |
| 65 | + } |
| 66 | + |
| 67 | + private String isValidIPv6(String IP) { |
| 68 | + if (getDelimiterCount(IP, ':') != 7) return NEITHER; |
| 69 | + String[] bytes = IP.split("\\:"); |
| 70 | + if (bytes.length != 8) return NEITHER; |
| 71 | + for (int i = 0; i < 8; i++) { |
| 72 | + if (hasInvalidIPV6Char(bytes[i])) return NEITHER; |
| 73 | + try { |
| 74 | + if (bytes[i].length() > 4) return NEITHER; |
| 75 | + int intNum = Integer.parseInt(bytes[i], 16); |
| 76 | + if (intNum < 0) return NEITHER; |
| 77 | + if (i == 0 && intNum != 0 && bytes[i].charAt(0) == '0') return NEITHER; |
| 78 | + } catch (Exception e) { |
| 79 | + return NEITHER; |
| 80 | + } |
| 81 | + |
| 82 | + } |
| 83 | + return "IPv6"; |
| 84 | + } |
| 85 | + |
| 86 | + private String isValidIPv4(String IP) { |
| 87 | + if (getDelimiterCount(IP, '.') != 3) return NEITHER; |
| 88 | + String[] bytes = IP.split("\\."); |
| 89 | + if (bytes.length != 4) return NEITHER; |
| 90 | + for (String num : bytes) { |
| 91 | + try { |
| 92 | + int intNum = Integer.parseInt(num); |
| 93 | + if (intNum > 255 || intNum < 0) return NEITHER; |
| 94 | + if (intNum != 0 ) { |
| 95 | + for (int i = 0; i < num.length(); i++) { |
| 96 | + if (num.charAt(i) == '0') return NEITHER; |
| 97 | + else break; |
| 98 | + } |
| 99 | + } else if (intNum == 0) { |
| 100 | + if (num.length() != 1) return NEITHER; |
| 101 | + } |
| 102 | + } catch (Exception e) { |
| 103 | + return NEITHER; |
| 104 | + } |
| 105 | + } |
| 106 | + return "IPv4"; |
| 107 | + } |
| 108 | + |
| 109 | + private boolean hasInvalidIPV6Char(String str) { |
| 110 | + Set<Character> set = new HashSet<>(Arrays.asList('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', |
| 111 | + 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F')); |
| 112 | + for (char c : str.toCharArray()) { |
| 113 | + if (!set.contains(c)) return true; |
| 114 | + } |
| 115 | + return false; |
| 116 | + } |
| 117 | + |
| 118 | + private int getDelimiterCount(String ip, char delimiter) { |
| 119 | + int count = 0; |
| 120 | + for (char c : ip.toCharArray()) { |
| 121 | + if (c == delimiter) count++; |
| 122 | + } |
| 123 | + return count; |
48 | 124 | }
|
49 | 125 |
|
50 | 126 | }
|
0 commit comments