摘要

  • RFC 3966 把电话 URI 的相等定义为结构化比较:视觉分隔符、字母大小写和参数书写次序可以不影响结果,但全局或本地形式、phone-context 以及每一个参数名仍然重要。
  • “相等”只说明两个标识符在该规范下指向同一电话资源;它不证明号码仍在分配、线路可达、路由相同、同一人会接听,也不构成拨号同意。

电话号码从来不只活在机器里。人会用括号标出区号,用连字符分组,也会按照本地习惯书写同一串数字。软件若把原始字符当作身份,就会把排版差异误作两个对象;软件若把所有差异都抹掉,又会把不同的编号范围合并。2004 年 12 月发布的 RFC 3966 选择了中间道路:先规定 tel URI 的结构,再准确列出比较时可以忘掉什么。

规范把 tel URI 称为“由电话号码标识的资源”的名称。它不是拨号脚本。取得外线所需的数字、国际拨号前缀、音频或脉冲选择、呼叫进程音处理以及拨号后的动作,都应由本地设备和配置决定。它也不承诺某一台物理电话:一个号码可能终结于固定、移动或游牧设备,还可能承载语音、数据、传真或别的服务。

这一边界比被它取代的 RFC 2806 更清楚。旧方案曾容纳运营商选择、拨号上下文动作、传真与调制解调器形式、暂停和拨号后字符串;RFC 3966 把动作从标识符中移走。保留动作型电话字符串历史的是 RFC 3601,而不是本篇讨论的相等算法。

比较器有选择地遗忘

比较两个 URI 时,号码中的 、.、(、) 属于视觉分隔符,应先移除;字母比较不区分大小写;参数按名称对应,不受它们在字符串中先后位置的影响。因此,肉眼明显不同、字节也不同的两个全局号码 URI,可能在语义上相等。

但遗忘到此为止。两个输入必须同为全局号码或同为本地号码。若一个是本地形式,另一个是全局形式,即使运营人员确信它们能拨到同处,RFC 算法也不会宣布相等。任意一方多出一个参数名,比较结果就是不相等。本地号码的 phone-context、分机 ext、ISDN 子地址 isub 和强制扩展都属于标识的一部分。

语法还给出了推荐的串行化次序:若有 isub 或 ext,先写它;然后写 phone-context;其他参数按词法排序。这让仍然依赖字符比较的系统更容易得到稳定输出。然而,收到两个 URI 后,正确的语义比较仍按参数名配对,而不是要求原文次序一致。规范化输出是一种工程便利,语义相等是一项判断规则,两者不能互相冒充。

RFC 3986 提供了通用 URI 框架;RFC 3261 则在 SIP 中使用电话用户语法,也暴露出周边系统可能对字符敏感的场景。可靠的证据系统应同时保存原始字符串、解析后的字段、每一步规范化记录和规范形式,而不是用最后一列覆盖最初的输入。

上下文让本地号码唯一,却不会替它选路

RFC 3966 优先推荐全局形式,但 PBX 分机、紧急号码和其他本地业务号码无法总是转换为全球号码。因此,本地形式必须带有 phone-context;它可以是受控域名,也可以是一段有效全球号码的前导数字。上下文与本地号码合在一起,目标是形成全局唯一的标识。

“合在一起”不等于字符串拼接。911;phone-context=+1 并不因此变成 +1-911。域名上下文也不必解析为某台主机;要求是它处于管理该本地编号空间的实体控制之下。于是,上下文说明编号在哪个命名空间中有意义,却不提供 DNS 网关、实时路由、当前分配状态或使用许可。

只把 URI 当标识符的接收者,可以把上下文当作不透明值;想真正发起呼叫的接收者,则必须理解该上下文并能在其中工作。即便是全局号码,规范也提醒它可能过期,或无法从某个位置到达。标识同一资源与成功抵达该资源,需要两套不同的证据。

相同的参数集仍可能不可使用

ext 表示非 ISDN PBX 后面的分机,isub 表示 ISDN 子地址,二者不能在同一 URI 中共存。RFC 4715 后来细化了 ISDN 子地址编码;RFC 4694、RFC 4759 与 RFC 4904 分别记录了号码携转、ENUM 查询和中继组等参数的发展。

更关键的是 m- 前缀。它为未来的强制参数保留:实现若不认识某个 m- 参数,就不得使用这个 URI。可选参数可以忽略,未知强制参数不可以。由此出现两个相邻但独立的问题:两份结构化标识是否相等;当前接收者是否有能力和权限使用它们。即使两边带着完全相同的未知强制参数,比较器能对齐字段,也不能替执行器取得理解。

RFC 5341 后来建立 tel URI 参数注册程序;当前的 IANA tel URI Parameters 注册表 使名称和定义可查。注册只证明协调过名称,不证明实例值为真、仍然新鲜、发送者有权声明,或接收者支持它。

电话资源不是人的替身

一次呼叫建立过程中,同一个 tel URI 可以被转换成多个其他 URI;信令还会协商服务类型。一个终结点可以拥有多个标识,一个号码也不必唯一选择某个终端或某个人。RFC 6116 后来描述从 E.164 号码经 ENUM 解析到服务和 URI 的过程,那只是增加了“何时返回了哪些记录”的新凭据,并未把 RFC 3966 的相等升级为真人身份断言。

安全条款同样拒绝这种越界。浏览器不能因为页面上出现 tel 链接就自动拨号,必须取得用户明确同意,因为呼叫可能收费、占线、泄露主叫信息或被恶意利用。链接显示的号码甚至可以与真正目标不同。解析后目标彼此相等,既不证明展示诚实,也不证明用户授权。

RFC Editor 信息页、勘误检索 与 IETF Datatracker 条目 能确认文档状态和已报告修正,却没有提供采用率、事故数量或通话结果。审计记录因此至少要分别保留:原始八位字节与显示文本、全局或本地形式、移除分隔符前后的数字、大小写转换、参数集合与接收顺序、规范次序、上下文类型和控制者、分机或子地址、强制参数识别与解析器版本、比较规则与结果。号码分配时效、拨号计划变换、信令目标、选定路由、同意、端点响应、真人接听、服务与费用,则应各有自己的凭据。

RFC 3966 的贡献不是把不同写法粗暴压成一个值,而是明确哪些差异仅为外观、哪些差异承载语义。它留下的治理原则也同样精确:比较规则没有观察到的现实,不能偷偷塞进“相同”二字。

来源