当前位置: 面试刷题>> 检验互联网协议(Internet Protocol,IP)地址 (经典算法题500道)


题目描述补充

题目: 检验一个给定的字符串是否是一个有效的IPv4或IPv6地址。IPv4地址由四组由点分隔的数字组成,每组数字在0到255之间(包括0和255),且不能包含前导零(除了数字0本身)。IPv6地址由八组由冒号分隔的十六进制数组成,每组可以是0到ffff之间的任何十六进制数(不区分大小写),并且可以使用双冒号“::”来表示连续的零组(但整个地址中只能出现一次)。

示例代码

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 示例

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。

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地址的规范。

推荐面试题