每个 IBAN 的第 3 和第 4 个字符是校验位。它们根据其余所有字符,用一种名为 MOD 97-10 的方法算出,这种方法由 ISO/IEC 7064 标准定义。您输入 IBAN 时,软件会重新算一遍;如果结果不对,就说明 IBAN 有输入错误。
四步校验一个 IBAN
以德国示例 IBAN DE89 3704 0044 0532 0130 00 为例。
- 去掉空格:
DE89370400440532013000。 - 把前四个字符移到末尾:
370400440532013000DE89。 - 把每个字母换成两位数字,A = 10,B = 11,依此类推,直到 Z = 35。这里 D 变成 13,E 变成 14:
370400440532013000131489。 - 用这个数除以 97,取余数。如果余数为 1,这个 IBAN 就是有效的。
在这个例子中,370400440532013000131489 除以 97 的余数正好是 1,所以校验位正确。
计算校验位
为新的 IBAN 生成校验位,步骤相同,只是先用 00 代替校验位:
- 写下国家代码,接着写
00和 BBAN:DE00370400440532013000。 - 按上面的方法调整顺序并转换:
370400440532013000131400。 - 计算它除以 97 的余数,这里是 9。
- 用 98 减去余数:98 − 9 = 89。如有需要,在前面补 0 凑足两位(例如 7 写成 07)。
校验位是 89,由此得到 DE89370400440532013000。第 4 步的结果总在 2 到 98 之间,所以有效 IBAN 的校验位永远不会是 00、01 或 99。
处理很长的数字
转换后的数字长度因国家而异:挪威为 17 位,德国为 24 位,含字母的马耳他 IBAN 超过 40 位。大多数都超出普通计算器和 64 位整数(约 19 位)的范围。可以把它拆成几段来算:先取前 9 位数字求余数,把余数写在接下来几位数字的前面,然后重复这个过程:
| 步骤 | 数字 | 除以 97 后的余数 |
|---|---|---|
| 1 | 370400440 | 23 |
| 2 | 23 + 5320130 = 235320130 | 70 |
| 3 | 70 + 0013148 = 700013148 | 38 |
| 4 | 38 + 9 = 389 | 1 |
最终余数是 1,与整个数直接相除的结果相同。
用代码实现同样的校验
JavaScript 版本,每次处理一位数字,因此不需要大数运算:
function isValidIban(input) {
const iban = input.replace(/\s+/g, '').toUpperCase();
if (!/^[A-Z]{2}\d{2}[A-Z0-9]{11,30}$/.test(iban)) return false;
const rearranged = iban.slice(4) + iban.slice(0, 4);
let remainder = 0;
for (const ch of rearranged) {
const value = parseInt(ch, 36); // 0-9 stay digits, A-Z become 10-35
remainder = (value > 9 ? remainder * 100 : remainder * 10) + value;
remainder %= 97;
}
return remainder === 1;
}
Python 版本,Python 的整数可以任意大:
def is_valid_iban(value: str) -> bool:
iban = "".join(value.split()).upper()
if not (iban.isascii() and iban.isalnum() and 15 <= len(iban) <= 34):
return False
rearranged = iban[4:] + iban[:4]
digits = "".join(str(int(ch, 36)) for ch in rearranged)
return int(digits) % 97 == 1
这些函数只检查结构和校验位。真正的验证程序还要检查该国是否使用 IBAN,以及长度是否与该国相符;本站支持的每个国家的长度都列在各国 IBAN 格式一文中。
如果只想手动检查一个 IBAN,可以把它粘贴到 IBAN 验证器中:它会显示哪项校验未通过;如果只是校验位不对,还会给出能让它通过的校验位。如果不想自己维护这段代码,可以使用 iban-check,这是我们为 JavaScript 和 TypeScript 开发的开源库。它依据 SWIFT IBAN 注册表完成全部检查,没有任何依赖。可通过 npm 安装:npm install iban-check。
校验能发现哪些错误
这种方法很擅长发现人们打字时犯的错误。任何一位数字输错,或任何两个相邻数字颠倒,都会改变余数,因此一定会被发现。其他错误大约每一百次会漏掉一次。
校验无法判断账户是否存在。校验位正确的 IBAN,仍然可能指向一个不存在的银行代码,或一个已经注销的账户。所以本站生成器生成的 IBAN 虽然没有任何银行发放过,却能通过校验。
国内校验位
有些国家按本国规则计算自己的校验位,放在 BBAN 中。意大利 IBAN 的 BBAN 以一个名为 CIN 的字母开头,法国和摩纳哥的 BBAN 以两位“clé RIB”结尾,西班牙在分行代码和账号之间有两位控制码,比利时的 BBAN 以两位校验位结尾。这些校验与 IBAN 校验位相互独立:一个 IBAN 可能通过了 MOD-97 校验,却没通过国内校验。IBAN 中的国内校验位一文逐国讲解了每种方法。
资料来源
- ISO/IEC 7064:MOD 97-10 校验字符系统。
- ISO 13616-1:2020:IBAN 如何使用这种方法,包括字母转换(A = 10 到 Z = 35)。
- SWIFT IBAN 注册表:各国的示例 IBAN 和长度。