

文章目录
摘要
《验证 IP 地址》是一道非常工程化的题。
它不像很多算法题那样考复杂技巧,而是更像我们在写后台接口、网关校验、日志解析时,经常会遇到的那种"脏数据判断"问题。
这道题的核心不在算法,而在于三点:
- 规则是否吃透
- 边界是否考虑完整
- 代码是否足够清晰、可维护
如果你平时写过参数校验、输入校验,这道题会让你有一种"这不就是我每天在干的事吗"的熟悉感。

描述
题目给你一个字符串 queryIP,要求判断它属于哪一种类型:
- 合法的 IPv4 → 返回
"IPv4" - 合法的 IPv6 → 返回
"IPv6" - 两者都不是 → 返回
"Neither"
IPv4 的规则可以总结成一句话
x1.x2.x3.x4
- 必须正好 4 段
- 每段是 0~255 的十进制数字
- 不能有前导零
- 只能是数字,不能夹杂奇怪字符
IPv6 的规则则是
x1:x2:x3:x4:x5:x6:x7:x8
- 必须正好 8 段
- 每段 1~4 位
- 只能是十六进制字符(0-9, a-f, A-F)
- 允许前导零
- 不支持
::这种缩写(这是本题特别容易踩的坑)
题解答案
整体解法非常直接,也非常"工程化":
-
先看分隔符
- 包含
.→ 尝试按 IPv4 规则解析 - 包含
:→ 尝试按 IPv6 规则解析
- 包含
-
严格按规则逐段校验
-
任何一条不满足,直接判
Neither
核心原则只有一个:
宁可判错为非法,也不能放过一个非法输入。

题解代码分析
下面是完整的 Swift 实现,结构清晰,逻辑拆分明确,可以直接运行。
swift
class Solution {
func validIPAddress(_ queryIP: String) -> String {
if queryIP.contains(".") {
return isValidIPv4(queryIP) ? "IPv4" : "Neither"
}
if queryIP.contains(":") {
return isValidIPv6(queryIP) ? "IPv6" : "Neither"
}
return "Neither"
}
private func isValidIPv4(_ ip: String) -> Bool {
let parts = ip.split(separator: ".", omittingEmptySubsequences: false)
if parts.count != 4 { return false }
for part in parts {
// 不能为空
if part.isEmpty { return false }
// 不能有前导零
if part.count > 1 && part.first == "0" {
return false
}
// 必须全是数字
guard let num = Int(part), num >= 0 && num <= 255 else {
return false
}
}
return true
}
private func isValidIPv6(_ ip: String) -> Bool {
let parts = ip.split(separator: ":", omittingEmptySubsequences: false)
if parts.count != 8 { return false }
for part in parts {
// 长度 1~4
if part.isEmpty || part.count > 4 {
return false
}
for ch in part {
if !ch.isHexDigit {
return false
}
}
}
return true
}
}
IPv4 校验逻辑拆解
swift
let parts = ip.split(separator: ".", omittingEmptySubsequences: false)
这里非常关键的一点是:
不能省略空字符串
否则像下面这种:
"192..168.1"
会被错误拆成 3 段。
swift
if part.count > 1 && part.first == "0"
这一步是专门防:
"01""001"
这是 IPv4 非常典型的坑点。
IPv6 校验逻辑拆解
IPv6 这边反而规则更"干净":
- 段数必须 8
- 每段最多 4 位
- 每个字符必须是十六进制
Swift 的这个 API 在这里非常好用:
swift
ch.isHexDigit
可读性和安全性都比手写判断强。
示例测试及结果
示例 1
swift
let solution = Solution()
print(solution.validIPAddress("172.16.254.1"))
输出:
IPv4
原因很简单:
4 段、范围合法、无前导零。
示例 2
swift
print(solution.validIPAddress("2001:0db8:85a3:0:0:8A2E:0370:7334"))
输出:
IPv6
大小写混用、前导零,全都允许。
示例 3
swift
print(solution.validIPAddress("256.256.256.256"))
输出:
Neither
单段数值超出 255,直接判非法。
时间复杂度
- IPv4:最多检查 4 段
- IPv6:最多检查 8 段,每段 4 个字符
整体时间复杂度:
O(n)
其中 n 是字符串长度,实际上非常小。
空间复杂度
只使用了拆分后的数组和少量变量:
O(1)
总结
《验证 IP 地址》这道题,非常不像"刷题",但非常像"真实工作"。
它真正考察的是:
- 你能不能严格遵守规则
- 你会不会遗漏边界
- 你的代码是否清晰、可维护、可扩展