菜单

IBAN 结构与 mod-97 校验:哪几段能拆开看

IBAN 的前四位是国家代码与两位 ISO 校验位,其后是各国自行规定的 BBAN,总长逐国不同。本文拆开每一段讲清用途,并说明 mod-97 校验具体校验了什么、没有校验什么。

发布于

  • IBAN
  • 校验位

同一个字段在不同国家长得完全不一样,这大概是最容易被低估的接口设计难题之一,IBAN 就是典型例子。它把「跨国能读」与「本国能用」两件事塞进了一串字符:前四位是国际层面统一规定的头,后面的部分交给各国自己定义。理解这个分层,比记住任何一串示例都有用。

IBAN 的结构分哪几段?

从结构上看,IBAN 可以按用途切成三段。最前面两位是国家或地区代码,用字母表示,它的作用是告诉读者这串号码属于哪一套登记体系。紧接着是两位校验位,用于验证整串字符是否自洽。第三段是 BBAN,也就是基本账户号,它内部的位数与含义完全由该国规定。

段 内容 由谁规定
最前两位 国家或地区代码 国际层面的结构约定
第 3 至 4 位 校验位 由整串字符按规则算出
其后部分 BBAN,基本账户号 由各国自行规定

这里的顺序是有意安排的:国际层面能判断的信息放在最前面,且长度固定;只有本国才知道含义的信息放在后面,长度可变。这样任何国家的阅读器都能先判断「这是不是我处理的体系」,再决定要不要继续往下解析。

需要强调的是总长度并非全球统一。它由各国在规则框架内确定,因此跨系统处理时不能用固定长度去切分,只能先按国家代码查到该国的长度,再校验整体。这一点在做表结构设计时尤其容易踩坑,字符型字段必须留足空间。

国家代码与两位 ISO 校验位

国家代码是这套结构里最稳定的一段。它不含算术,只是标识。真正参与计算的是紧随其后的两位校验位,它的取值由整串号码其余部分共同决定,因此改动任何一个字符都会让它对不上。

这对使用者的实际意义是:校验位让你在本地就能发现输错、漏位或粘贴截断,而不必先发出一次远端查询。对于人工录入场景,这一步能挡掉相当一部分明显错误的输入,也能让错误提示更早出现。

但两位校验位能承载的信息有限,它只回答「这串字符是否自洽」。任何知道规则的人都能为任意国家代码与账户部分算出两个让校验成立的字符,所以它同样不承担防伪作用。把它当成真实性证据,是一个方向性的误用。

BBAN 里为什么还有本国校验位

因为 BBAN 的内部结构由各国自己规定,很多国家在账户号内部又放了一处本国校验位。于是会出现看起来重复的现象:整串已经有一位国际校验,局部还有一位本国校验。

这两者不冲突,服务的读者也不同。国际校验位服务于跨系统处理,任何国家的实现都能验;本国校验位服务于本国系统内部的快速判断,可以在只拿到账户部分、还没有拼出完整 IBAN 时先做一次检查。两处算法也可能完全是不同的家族成员。

对使用者的启示是:不要假设「账户部分合法」与「整串合法」等价。一个在局部成立的值,拼上国家代码与校验位之后仍可能不成立——通常是因为拼接时位数或顺序弄错了。

处理这类数据的经验是:把账户部分与完整号码当成两个独立的检查对象,各自留一个结论字段。只存一个通过与否的标志,事后很难还原问题出在哪一段,尤其在数据来自多个渠道、各自的拼接方式还可能不同的时候。

把字母换成数字:mod-97 的算法思路

整串校验的做法可以概括成三步:先按规则重排字符顺序,再把其中的字母按固定方式替换成数字,最后把得到的长数字串对九十七取模,看余数是否落到规定的值上。之所以要重排,是为了让校验位参与在末尾而非开头,计算顺序才与常见写法一致。

模数取九十七并不是随意的选择。它大于所有单字符替换后可能出现的两位数取值,因此替换过程不会因为进位而丢失信息,整串保留了对每一位的敏感性。这也解释了为什么长号码体系偏爱大模数:位数越多,小模数越容易让不同输入落到同一结论上。

算法本身是公开的,实现难度也不高,真正的难点在集成:字符替换规则、大小写处理、以及重排的边界条件,任何一处写错都会让整串校验在所有输入上系统性偏移。

通过校验为什么不代表账户存在?

mod-97 校验确认的只有一件事:这串字符自洽。账户是否真实存在、属于谁、能否收款,取决于该国登记体系里的记录,而 IBAN 本身不编码这些信息。国家代码说明的是体系归属,不是某个具体机构的承诺。

也正因为如此,很多场景要求的不只是校验通过,还包括一次在册查询或人工核对。而这类查询有它自己的工程约束:可能超时、可能被限流、可能对同一账户返回不同时点的状态。把校验结论与查询结论分开记录,出问题时才分得清是哪一层的责任。

同理,校验失败也不该被表述成「账户不存在」。正确的说法是这串字符没有通过它所属体系的校验位算法,通常意味着录入有误,也可能意味着格式本身就不是这个体系。

给开发者:长度差异与按国家分流

实现上建议把 IBAN 处理拆成两步:先归一化去分隔符并统一大小写,再按国家代码查表,取出该国规定的位置与长度约束。查不到国家代码时,结论应当是本地没有对应规则,而不是格式错误。

第二步才是算法校验。校验与解析尽量分开输出:校验给四态结论,解析给分段标签。分段标签需要国家表支撑,没有表时宁可只给出整串长度,也不要猜内部结构。字符集与长度的通用判断逻辑,见号码校验的原理;模数的取舍与家族成员差别,见校验位算法家族。

还有一个常被忽略的细节:归一化后应当把参与校验的字符原样保留在返回值里,方便排查。如果只回一个布尔值,前端拿不到是哪一串失败,日志里也就没有了线索。有些体系的局部校验位本身就缺失,这时只能给「仅格式」结论,可参考没有校验位的号码。

下一步

把手上任意一串 IBAN 粘贴进号码校验工具,观察它把输入分成了哪几段、每一段给出了什么依据,这比只看通过与否更能发现录入问题。如果要做批量处理,先确认你的字段长度对目标国家的位数有余量,再谈校验逻辑。

本文描述的是 IBAN 的公开结构约定,文中不含任何真实账户信息;通过本文说明的结构校验只能确认字符自洽,不构成对账户存在性、归属或可收款性的任何保证。

继续阅读

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