题目描述
编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址。
- 如果是有效的 IPv4 地址,返回 "IPv4" ;
- 如果是有效的 IPv6 地址,返回 "IPv6" ;
- 如果不是上述类型的 IP 地址,返回 "Neither" 。
IPv4 地址由十进制数和点来表示,每个地址包含四个十进制数,其范围为 0 - 255,用(".")分割。
比如,172.16.254.1;
同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。
IPv6 地址由 8 组 16 进制的数字来表示,每组表示 16 比特。这些组数字通过 (":")分割。
比如,2001:0db8:85a3:0000:0000:8a2e:0370:7334 是一个有效的地址。
而且,我们可以加入一些以 0 开头的数字,字母可以使用大写,也可以使用小写。
所以, 2001:db8:85a3:0:0:8A2E:0370:7334 也是一个有效的 IPv6 表示法(即,忽略前导 0)。
示例:
输入:IP = "172.16.254.1"
输出:"IPv4"
解释:有效的 IPv4 地址,返回 "IPv4"
输入:IP = "2001:0db8:85a3:0:0:8A2E:0370:7334"
输出:"IPv6"
解释:有效的 IPv6 地址,返回 "IPv6"
解题思路
分别判断输入字符串是否是 IPv4 或 IPv6 即可。
对于 IPv4 来说,需要先判断字符串中 "." 的个数是否为 3,然后将字符串用 "." 分割成 4 个子字符串(即四段 IP 地址),再判断每一段是否合法(大于等于 0 小于等于 255 且没有前导零)。
对于 IPv6 来说,需要先判断字符串中 ":" 的个数是否为 7,然后将字符串用 ":" 分割成 8 个子字符串(即八段 IP 地址),再判断每一段是否合法(只包含数字和字母,长度不超过 4)。
注意:在判断 IPv6 段的合法性时,需要转换为小写字母再进行判断。
代码实现
function validIPAddress(IP: string): string {
if (IP.indexOf('.') !== -1 && isValidIPv4(IP)) {
return 'IPv4';
} else if (IP.indexOf(':') !== -1 && isValidIPv6(IP)) {
return 'IPv6';
} else {
return 'Neither';
}
}
function isValidIPv4(ip: string): boolean {
const nums = ip.split('.');
if (nums.length !== 4) return false;
for (const num of nums) {
if (num === '' || num.length > 1 && num[0] === '0') return false; // 长度大于 1 且第一位是 0 的不合法
const n = Number(num);
if (isNaN(n) || n < 0 || n > 255) return false;
}
return true;
}
function isValidIPv6(ip: string): boolean {
const nums = ip.split(':');
if (nums.length !== 8) return false;
for (const num of nums) {
if (num === '' || num.length > 4) return false;
for (const ch of num) {
if (!/[0-9a-fA-F]/.test(ch)) return false;
}
}
return true;
}
时间和空间复杂度
-
时间复杂度:,其中 为输入字符串的长度。
-
空间复杂度:,