带命名位与可扩展长度约束的BIT STRING的PER编码长度问询
问题核心
给定类型定义:
X ::= BIT STRING {a(0), b(1)} (SIZE(2, ...))
值'00'B的PER编码应使用的正确长度存在争议:
- 我认为编码长度应为0:依据X.691 16.3要求,需修剪到「能够承载该值且满足有效长度约束的最小长度」,而X的可扩展约束允许长度为0的值。
- 部分工具采用长度2编码,核心歧义点在于「满足有效长度约束」的定义不够明确。
推导:X与X-V2的编码一致性假设
进一步假设类型定义:
X-V2 ::= BIT STRING {a(0), b(1)} (SIZE(2, ..., 0))
无论如何解读,长度0都满足该类型的有效长度约束,因此'00'B必须按长度0编码。为实现规范PER编码的一致性,X与X-V2对'00'B的编码方式必须一致,因此X的'00'B也应使用长度0。
歧义根源:可扩展类型的取值范围定义
X.691相关定义
3.7.8 有效长度约束(针对受限字符串类型):可应用于内置字符串类型的单一有限长度约束,其作用是允许且仅允许受限字符串类型中可能存在的所有长度。
10.3.10 受限类型的有效长度约束是单一长度约束,当且仅当受限类型存在某个取值具有该长度时,该长度才被允许。
X.680中关于可扩展类型的矛盾表述
观点1:可扩展类型包含根值与扩展新增值
Annex I 4.2.3:
A1 ::= INTEGER (1..32, ... , 33..128)A1是可扩展类型,包含1至128的取值,其中1至32为根值,33至128为扩展新增值。
50.1注6:
注6:“ElementSetSpecs”引用的元素是“RootElementSetSpec”与(若存在)“AdditionalElementSetSpec”引用元素的并集。
观点2:可扩展类型包含被约束类型的所有取值
第6节:
形式上,可扩展类型X定义的抽象语法不仅包含X类型的取值,还包含所有与X扩展相关的类型的取值。
3.8.38:
扩展相关:具有相同扩展根的两个类型,其中一个是通过向另一个添加零个或多个扩展新增项创建的。
我认为第6节的定义具有优先性,Annex I 4.2.3与50.1注6的表述不够精确。
更新:X.691 16.3与16.6的逻辑顺序解读
针对Alessandro提出的「先应用16.6再应用16.3」的观点,我的解读如下:
- 16.3的无限制适用性
16.3的表述未限定仅适用于PER可见约束不可扩展的场景,也未要求结合16.6理解其应用方式。它使用的「有效长度约束」术语定义不依赖于16.6,且规范中存在可扩展的有效长度约束示例(Annex B.3):
A13 ::= IA5String (SIZE(1..10, ...) ^ FROM("A".."D")) -- A13的有效长度约束为可扩展的SIZE(1..10,...)
16.6的分支逻辑含义
16.6提到「在后一种情况下,长度和值应按约束中不存在扩展的方式进行编码」,并未要求回到16.1重新执行,也未明确需调用16.3。该表述仅意味着执行后续的16.7时,应假设不存在扩展标记;而16.7指出「若位串类型的约束规范中不存在扩展标记,则应用16.8至16.11」,这说明16.6的两个分支最终都指向长度编码方式的规则,这是最自然的解读。「此编码的长度」的语义解读
16.6要求根据「此编码的长度」是否在扩展根内选择分支,该术语只能指代「字符串值的长度」或「编码中使用的长度」。除非16.3在逻辑上先于16.6应用,否则无法指代「编码中使用的长度」。
举个例子,给定类型:
Y ::= BIT STRING {a(0), b(1)} (SIZE(0..4, ...))
若假设「此编码的长度」仅指字符串原始长度,且仅当原始长度在根内时才应用16.3,那么:
'11000'B(长度5)不会被修剪'1100'B(长度4)会被修剪至长度2
这种「短值被修剪、长值不修剪」的结果不符合直觉,且表述中「此编码的长度」与实际编码使用的长度不一致,显得逻辑混乱。
正是16.3导致了字符串原始长度与编码使用长度的差异,因此「此编码的长度」自然应理解为经过16.3处理后确定的编码长度,这意味着16.3在逻辑上必须先于16.6应用。
基于此解读,存在部分取值被编码为扩展值但更适合编码为根值的情况(比如修剪后长度短于根覆盖范围),但这是对规范最自然的解读。核心歧义仍在于16.3中「满足有效长度约束」的定义:长度0是否满足SIZE(2, ...)?我认为答案是肯定的,至少规范未明确否定这一点。
更新2:反驳论点分析
针对上述解读,存在两个关键反驳论点:
类似条款的措辞参考
正如Alessandro指出,针对八位字节串的17.3与针对序列的20.4和16.6类似,其中「此编码的长度」「此编码中的组件数量」实际仅指代取值的原始长度/组件数量。这暗示16.6中的「此编码的长度」可能也是指原始字符串长度,可能是规范措辞的无意失误。16.6「按无扩展方式编码」的范围
16.6要求「按约束中不存在扩展的方式进行编码」,该规则不仅适用于后续条款,也必须适用于之前的16.4(否则可扩展类型永远无法使用优化长度编码)。若该规则适用于16.4,那么也应适用于16.3:
对于类型X,'00'B的原始长度为2,属于根值范围,因此需按SIZE(2)而非SIZE(2, ...)的约束编码,即16.3不会对字符串进行修剪,编码长度应为2。
衍生问题
该解读会引发新的疑问:
- X的取值
'1110'B(长度4,不在根内):16.6不要求按无扩展方式编码,规范未明确是否需修剪末尾零位。X.680 22.7指出应用设计者应将'1110'B与'111'B视为语义等价,编码规则可自由添加/删除末尾位,但这仅说明PER可以修剪,而非必须修剪,无法明确正确编码方式。 - X的取值
'1100'B(长度4,不在根内):语义上等同于'11'B(长度2,在根内),编码为相同形式合理,但规范未明确要求。 - X的取值
''B(长度0,不在根内):语义上等同于'00'B,按此解读'00'B需按长度2编码,逻辑上存在不一致。
结论
ITU-T需要对该规范进行澄清,因为正反论点均不具有决定性,规范本身存在固有模糊性。
内容的提问来源于stack exchange,提问作者Kevin

