三条缩写规则
IPv6 地址写全太长,RFC 4291 允许三种缩写:每组的前导零可以去掉(0db8 写成 db8);一段连续的全零组可以用 :: 代替;字母统一小写。RFC 5952 进一步规定了书写细节,其中最关键的一条是 :: 在一个地址里只能出现一次,否则地址无法唯一还原。
RFC 5952 的排序规则
当存在多段可以缩写的零组时,规范要求把最长的连续零串用 :: 替代,不要求全零组也是同样处理。更细的规则是:如果有多个长度相同的零串,取最左边的那一段;单个全零组不得用 :: 缩写。这些规则的目的是让同一个地址在所有设备上有唯一的规范写法,便于比较与去重。
基本信息
| 规则 1 | 每组去掉前导零:0db8 → db8、0001 → 1 |
|---|---|
| 规则 2 | 连续全零组用 :: 代替,整个地址只能出现一次 |
| 规则 3 | 字母小写:2001:DB8::1 应写 2001:db8::1 |
| 规范依据 | RFC 4291(基础)、RFC 5952(文本表示推荐) |
典型使用场景
- 读懂设备回显、日志与抓包里的缩写地址
- 写配置时按规范书写,避免不同设备解析差异
- 脚本里比较两个地址是否相同前先展开成完整形式
- 编写正则匹配 IPv6 地址时理解 :: 的边界情况
- 考试与面试题中还原缩写地址的原貌
缩写与还原示例
缩写与还原示例
原始:2001:0db8:0000:0000:0000:0000:0000:0001
① 去前导零:2001:db8:0:0:0:0:0:1
② 最长零串用 :::2001:db8::1
③ 小写:已是小写
注意:2001:db8:1::1 里的 :: 代表 5 个零组
还原后为 2001:0db8:0001:0000:0000:0000:0000:0001用 Python 展开与规范化
用 Python 展开与规范化
import ipaddress as ip
print(ip.IPv6Address('2001:db8::1').exploded)
# 2001:0db8:0000:0000:0000:0000:0000:0001
print(ip.IPv6Address('2001:0db8:0000:0000:0000:0000:0000:0001').compressed)
# 2001:db8::1 ← RFC 5952 规范写法
print(ip.IPv6Network('2001:db8::/32').num_addresses) # 2**96常见写法与陷阱
| 写法 | 是否合法 | 说明 |
|---|---|---|
| 2001:db8::1 | 合法 | :: 代表连续零组 |
| 2001::db8::1 | 非法 | 两个 :: 无法唯一还原 |
| 2001:0db8:0:0:0:0:0:1 | 合法 | 未缩写的完整形式 |
| 2001:DB8::1 | 可解析 | 但规范要求小写 |
| ::1 | 合法 | 回环地址,前 7 组全零 |
| :: | 合法 | 未指定地址,全零 |
:: 的作用是补足缺失的零组:一个地址固定 8 组,读到 :: 就要用 8 减去已写出的组数得到被省略的组数。因此 2001:db8::1 里的 :: 代表 5 组零,而不是 1 组。
两个 :: 会让地址产生多种还原结果,属于非法写法。与之相关的高危场景是 ACL 与地址对象:如果比较的是字符串而非展开后的二进制,同一地址的不同写法可能被当成两个对象,导致规则漏配。