IBAN 校验与解析
在浏览器本地校验国际银行账号:国家代码、注册长度、ISO 7064 MOD 97-10 校验位,并输出结构拆解与打印格式。
这个账号在结构上成立吗? 粘贴 IBAN,带不带空格都可以。校验全程在浏览器本地完成:先比对 SWIFT 注册表中的国家代码,再核对总长度,最后计算 ISO 7064 MOD 97-10 校验位。
在浏览器本地校验国际银行账号:国家代码、注册长度、ISO 7064 MOD 97-10 校验位,并输出结构拆解与打印格式。
这个账号在结构上成立吗? 粘贴 IBAN,带不带空格都可以。校验全程在浏览器本地完成:先比对 SWIFT 注册表中的国家代码,再核对总长度,最后计算 ISO 7064 MOD 97-10 校验位。
IBAN 并不是一种全新的账号,它就是原有的国内账号(称为 BBAN),在前面拼上四个字符:两位 ISO 3166 国家代码和两位校验位。这四个字符之后的内容,完全沿用各国银行体系原本的编号方式——这正是长度差异如此之大的原因。挪威的 IBAN 是 15 位,马耳他的是 31 位,两者都完全正确。
这种长度差异构成了第一道真正的校验,也是最常被跳过的一步。每个国家都在 SWIFT 注册了确切的总长度,这是固定值而非上限。德国 IBAN 永远是 22 位。如果你收到一个 DE 开头的 21 位字符串,那无论校验位算不算得过都是错的——因为让字符串变短的错误,校验位根本"看不到"缺失的那个字符。先查国家长度还有一个好处:给出的错误提示远比一句笼统的"校验失败"有用。
校验算法来自 ISO 7064,思路相当优雅:把前四个字符挪到末尾,把每个字母替换成数字(A 为 10,一直到 Z 为 35),然后把整串当作一个巨大的整数来读。如果这个整数除以 97 的余数恰好是 1,IBAN 就通过。
麻烦在于这个数远超任何语言的原生整数类型,常常有八十位以上。实现上不必引入大数库,而是分段取模:从左到右遍历字符串,每处理一位就只保留对 97 取模后的运行值。由于模运算对逐位构造具有分配性,最终余数与用完整数字计算的结果完全一致,而代价只是一次遍历、零额外内存分配。本工具正是这么做的。
之所以选择 MOD 97-10,是因为对于仅仅两个校验字符来说它异常强健:能检出所有单字符替换、所有相邻两字符换位,以及绝大多数更长的乱序。它检测不到的错误形态非常罕见,剩余风险主要来自"账号本身并不存在"这一层。
结构有效不等于账户存在。一个校验位正确的 IBAN,可能指向一个已销户的账户、一个从未开立的账户,或一家早已被合并掉的银行。唯一能确认钱会到账的方式是发起转账,或使用银行提供的验证服务。请把校验当作录入环节的错别字拦截,而不是收款方真实性的证明。
格式同样需要注意。注册表定义的电子格式是不含空格的连续字符串,支付文件里传输、数据库里存储都必须用这一种。每四位一组的形式只用于纸面打印,目的是帮人准确抄写长串数字。正确做法是:录入时归一化,存储用无空格形式,仅在展示时再把空格加回去。