宽进严出优于一律拒绝
别名: 宽进严出 · 输入规范化 · tolerant input
概念解释
宽容读取、规范写出(tolerant reader, canonical writer)是指输入端接受多种等价且可安全解释的本地写法,解析后用明确的规范形式存储、交换或输出。这里的“宽进”是可追溯的输入规范化(input normalization),不是忽略错误;“严出”是稳定、无歧义、带类型与单位的输出契约,不是把未经确认的猜测写成事实。若两个输入可能代表不同值,系统必须询问或拒绝,不能静默选一个。
机制
人会输入熟悉的空格、连字符、大小写、全角/半角字符和本地分组,外部系统则需要稳定的数据才能比较、去重、计算和交换。先把已知等价的表面差异解析成结构化值,可以减少无意义的误拒;由同一结构化值生成规范输出,则避免每个下游重新猜测。但规范化存在语义风险:去掉小数或日期分隔符、转换 Unicode 字符、改变前导零,可能将一个值变成另一个值。可靠流程因此是“保留原文—解析—确认歧义—生成规范值”,并记录所用规则版本。
怎么研究
建立输入变体语料,将每个样本标为等价、可解析但有歧义、明确无效或未知,并由目标地区使用者复核标签。分别测量合法变体接受率、无效输入漏过率、静默改值率、确认请求率和往返一致性。性质测试可检查 parse(format(value)) 是否保持同一语义值,差分测试则比较客户端、服务端、导入器和导出器是否采用同一解析契约。研究报告应单列被“成功”接收但语义改变的案例,因为它们比显式拒绝更难发现。
边界
只有在等价关系明确、转换可说明且不会越过业务或安全边界时才适合自动规范化。金额、小数、日期、单位、姓名、密码、签名材料和不透明标识符可能含有看似装饰、实则有意义的字符;对它们应用通用去空格、改大小写或字符折叠可能损坏数据。外部协议若要求逐字保真,应保留原始表示;高风险或不可逆操作遇到歧义时,应展示解释结果并请求确认。
怎么落地
- 为每个字段定义接受语法、允许的等价转换、歧义条件、规范内部类型与输出格式;不要复用一个全局“清洗字符串”函数。
- 保留原始输入以及解析后的结构化值,记录解析规则版本。仅自动执行已证明语义不变的转换,并在回显中让用户看见结果。
- 对日期顺序、小数分隔符、单位或字符身份无法唯一判断的输入,要求补充上下文或确认;绝不通过默认地区静默改值。
- 成功解析必须消费除明确许可的首尾空白外全部输入;剩余字符应触发错误或确认。为 API、文件导出和界面显示规定类型、时区、单位、精度、编码和缺失值,并用含尾随垃圾、重复单位与拼接值的语料做 parse–format–parse 往返测试。