当前位置: 面试刷题>> 检验互联网协议(Internet Protocol,IP)地址 (经典算法题500道)
### 题目描述补充
**题目**: 检验一个给定的字符串是否是一个有效的IPv4或IPv6地址。IPv4地址由四组由点分隔的数字组成,每组数字在0到255之间(包括0和255),且不能包含前导零(除了数字0本身)。IPv6地址由八组由冒号分隔的十六进制数组成,每组可以是0到ffff之间的任何十六进制数(不区分大小写),并且可以使用双冒号“::”来表示连续的零组(但整个地址中只能出现一次)。
### 示例代码
#### PHP 示例
```php
function isValidIP($ip) {
// IPv4 验证
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
return true;
}
// IPv6 验证
$ip = strtolower($ip); // 转换为小写以统一处理
$parts = explode(':', $ip);
$compressed = false;
$zeros = 0;
if (count($parts) > 8) {
return false; // 超过8组
}
foreach ($parts as $part) {
if ($part == '') {
if ($compressed) {
return false; // 已经压缩过,再次出现空组
}
$compressed = true;
$zeros++;
if ($zeros > 1) {
return false; // 压缩部分超过一次
}
continue;
}
if (!ctype_xdigit($part) || strlen($part) > 4) {
return false; // 非十六进制或长度超过4
}
}
// 如果有压缩,则检查压缩后是否仍然有正确的组数
if ($compressed) {
$totalParts = count($parts) + 8 - $zeros;
if ($totalParts > 8) {
return false;
}
}
return true;
}
// 测试
echo isValidIP("192.168.1.1") ? "Valid IPv4" : "Invalid";
echo PHP_EOL;
echo isValidIP("2001:0db8:85a3:0000:0000:8a2e:0370:7334") ? "Valid IPv6" : "Invalid";
echo PHP_EOL;
echo isValidIP("2001:db8::8a2e:370:7334") ? "Valid IPv6 with compression" : "Invalid";
```
#### Python 示例
```python
import ipaddress
def isValidIP(ip):
try:
# 尝试将字符串解析为IPv4或IPv6
ipaddress.IPv4Address(ip)
return True
except ipaddress.AddressValueError:
pass
try:
ipaddress.IPv6Address(ip)
return True
except ipaddress.AddressValueError:
pass
return False
# 测试
print(isValidIP("192.168.1.1")) # 输出: True
print(isValidIP("2001:0db8:85a3:0000:0000:8a2e:0370:7334")) # 输出: True
print(isValidIP("2001:db8::8a2e:370:7334")) # 输出: True
```
#### JavaScript 示例
JavaScript 原生没有直接验证IPv6的内置函数,但可以通过正则表达式来辅助判断IPv4,并编写额外的逻辑来检查IPv6。
```javascript
function isValidIPv4(ip) {
const regex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
return regex.test(ip);
}
// IPv6 验证较复杂,这里简化处理,不实现完整的压缩逻辑
function isValidIPv6(ip) {
// 转换为小写
ip = ip.toLowerCase();
// 基本检查:分组数、十六进制、双冒号
// 这里只是简化示例,未实现完整逻辑
const regex = /^([0-9a-f]{1,4}:){7}[0-9a-f]{1,4}$/;
return regex.test(ip) || (ip.includes('::') && /^[0-9a-f:]+$/i.test(ip) && ip.split(':').filter(Boolean).length <= 8);
}
function isValidIP(ip) {
return isValidIPv4(ip) || isValidIPv6(ip);
}
// 测试
console.log(isValidIP("192.168.1.1")); // 输出: true
console.log(isValidIP("2001:0db8:85a3:0000:0000:8a2e:0370:7334")); // 输出: true(简化版可能不精确)
console.log(isValidIP("2001:db8::8a2e:370:7334")); // 输出: true(简化版可能不精确)
// 码小课网站中有更多相关内容分享给大家学习
```
注意:JavaScript 的 IPv6 验证示例中简化了压缩逻辑和双冒号的处理,实际使用时可能需要更复杂的逻辑来完全符合IPv6地址的规范。