菜单

号码校验的原理:字符集、长度与校验位

号码校验的原理是把字符集、长度与校验位三层依次套上去,三层能发现的错误类型完全不同。本文讲清校验的正确顺序、四种结论的差别,以及为什么格式正确并不等于号码真实。

发布于

  • 校验位
  • 表单校验

一个编号里通常藏着一位不属于信息本身的字符,它的唯一用途是让人发现抄录时出的错,这就是校验位的由来。号码校验的原理,就是把「这串字符合不合法」「长度对不对」「由其余位算出的校验位能不能对上」这三件事按正确顺序问一遍。读完本文,你能准确说出一次校验通过到底证明了什么,以及它没有证明什么。

什么是号码校验?

号码校验是用一套公开规则判断一串输入是否自洽的过程。它不联网、不查库、不联系签发机构,只做字符层面的比对与一次算术。你手上这串字符要么落在规则允许的形状里并且校验位成立,要么不成立,没有第三种解释。

正因为它是纯算术,同一条规则可以被任何人独立实现。这意味着两件事:第一,校验结果可复现,你换个工具或自己写一遍,结论应当一致;第二,任何知道规则的人都能为任意的前缀算出能让校验位成立的结尾,所以校验位从来不承担防伪职责。

它与「在册查询」是两件不同的事。在册查询问的是某个编号有没有被某个机构登记、状态是否正常;号码校验只问这串字符自不自洽。把两者混在一句话里,是绝大多数误报的起点。

三层层层过滤:字符集、长度、校验位

三层过滤各管一段,能拦下的错误并不重叠。先看字符集:该制度只允许数字,就应当拒绝字母与符号;允许字母数字混排,就还要决定大小写是否敏感。再看长度:这是该制度规定的位数范围,通常由签发机构定义,逐国、逐制度而异。最后才是校验位:由前面的位按公布的算法算出末位,比对是否一致。

层 主要拦下的错误 拦不下的错误
字符集 混进字母或符号、粘贴带上了多余字符 数字写错、数字换位
长度 少一位、多一位、截断 长度对但内容错
校验位 单个数字写错、多数相邻两位互换 伪造的自洽值、已停用的号码

顺序不能颠倒。如果先算校验位再检查字符集,一个混入了字母的输入会在第一关就报出奇怪的结论;如果先查长度再归一化,一个带连字符的正确号码会被判成过长。按「先清洗、再形状、后算术」的顺序走,每一层的错误信息才指向真正的原因。

为什么「格式对」不等于「号码真」?

校验位是一道完全公开、可以逆推的算术题。给定一串前面的位,任何人都能在毫秒内算出唯一一个让总和成立的末位。因此「校验通过」这句话的真实含义只有一句:该值通过了这项制度公布的校验位算法,字符之间彼此自洽。

它不回答的问题反而更多:这个号码有没有被发行过,属于谁所在的主体,当前是否有效,能不能拿去收款或办理业务。这些都要靠另一层查询,而那一层有自己的可用性、限流与超时问题。

还有一类情况常被忽略:很多制度从未公布校验位算法。此时连算术这一层都做不了,只能确认位数与字符结构。诚实的做法是把这种情况单独说成「仅格式」,而不是含糊地写成有效。

一个号码可能同时属于多个制度

不同制度规定的形状偶尔会重叠,同一个字符串在两三套规则下都可能是合法形状,甚至恰好都通过校验。这不是异常,而是位数与字符集相近的制度之间必然出现的巧合。

工具因此不该替你猜一个国家。合理的做法是把所有真正成立的说法并列出来,作为「可能的制度」呈现,并注明每一条的依据,也就是它套用了哪套规则。你自己知道手上这串号码的来源,比工具从形状反推可靠得多。

反过来,当输入确实对不上任何已知规则时,结论应当是「无法识别」,含义是本站没有对应规则,而不是这串号码是假的。这两句话的差别,决定了用户下一步该去核对数据源,还是该换一个工具。

判断候选制度时有一个实用原则:先看来源,再看形状。号码来自哪个国家的哪个业务,往往由数据源的字段直接给出,比从字符形态反推可靠得多。只有在来源完全未知时,才需要回到形状层面去列出所有可能。

这也意味着同一个号码在不同上下文里的处理方式可以不同。列表页只需要确认它写对了,提交流程可能还需要一次在册查询。把两种需求塞进同一个「校验」按钮,界面上的措辞就很难同时准确,用户也就分不清这个标记到底意味着什么。

归一化:空格、连字符与大小写

人写号码习惯加分隔:银行卡号每四位一个空格,税号里插点或斜杠,书号用连字符分段。这些分隔符方便阅读,却会让同一个号码长出许多种写法。归一化就是先把它们全部去掉,把字母统一成同一种大小写,再拿结果去做形状与算术判断。

归一化本身不是安全措施,也不能修复真实的输入错误。它只解决「同一个值的两种写法被当成两个值」这类问题。因此界面通常会把规范化后的号码单独显示一行,让用户看到校验的到底是哪一串字符——这一点在粘错内容时尤其有用。

表格软件导出的数据里还常带着不可见的空白或前导符号,肉眼看不出来,却足以让一条本该通过的记录失败。清洗时顺手去掉这些字符,比事后逐条排查省事得多。

给开发者:校验管线的层次划分

建议把校验写成一条分工明确的管线,每一步只负责一个判断:先归一化,再验字符集,再验长度,然后按形状分流到候选制度,最后由各自的规则计算校验位,输出结论。

结论的取值不要压成布尔值。至少要有四态:校验通过、校验失败、仅格式、无规则。前两者是算术结论,第三个表示该制度没有公布算法、只能确认格式,第四个表示本地没有对应规则。把「仅格式」折叠进「有效」或「无效」,都会向用户传递一个你自己并不掌握的判断。

错误信息里带上依据也很重要。同样一句校验失败,如果附上「依据该制度的校验位规则」,用户就能自己复查;如果什么都不说,用户只能反复猜测。各支算法的差别与选型,另见校验位算法家族。

下一步

手上有可疑的号码或从表格里导出的清单,直接用号码校验工具粘贴一条试试,看它给出的是四态中的哪一种,以及依据来自哪套规则。看清楚结论的分寸,再决定要不要把它写进你的表单提示语。

想继续往下读,建议先看没有校验位的号码那一篇:它专门讲「仅格式」这一类结论该怎么处理。如果你更关心校验位在真实数据里怎么用,证件号校验位那篇从测试数据角度做了补充。

本文出现的号码、示例与校验结论全部是为说明算法而虚构构造的合成示例,不对应任何真实存在的个人、账户或证件,也不能用来主张某个号码真实、有效或可以使用。

继续阅读

卡号与身份证号校验工具相关文章