手把手写一个 IBAN 校验器:ISO 13616 与 MOD 97 算法全解

手把手写一个 IBAN 校验器:ISO 13616 与 MOD 97 算法全解

跨境支付、外贸收款、海外开户,几乎处处都会碰到 IBAN。这篇文章不讲玄学,直接从标准出发,把 IBAN 的结构和校验算法拆开,最后用 JavaScript 手写一个可用的校验器。

为什么需要校验 IBAN

IBAN(International Bank Account Number,国际银行账号)是跨行、跨境识别银行账户的标准化格式,定义在 ISO 13616 标准中。它解决了各国账号格式不统一、跨境转账容易填错的问题。

但 IBAN 不是随便一长串数字——它自带“校验位”,通过一个公开的算法就能判断账号在结构上是否合法。填错一位字符、长度不对、校验位不匹配,都是转账被退回的高发原因。所以无论是工具还是业务系统,在校验 IBAN 上花点功夫都值得。

IBAN 的结构

一个 IBAN 由固定几部分组成:

DE 89 3704 0044 0532 0130 00
│  │  └──────────────┬───────┘
│  │          BBAN(各国自定义)
│  └─ 两位校验位(Check Digits)
└─ 两位国家代码(ISO 3166)
  • 前 2 位:国家代码(ISO 3166-1 alpha-2),例如 DE 代表德国、GB 代表英国。

  • 第 3-4 位:两位校验位,由账号信息通过 MOD 97 算法计算得出。

  • 剩余部分:BBAN(Basic Bank Account Number),包含银行代码、分行代码和账号,具体结构由各国自行定义。

IBAN 最长 34 位,不同国家长度不同,例如:

国家 长度 示例
德国 DE 22 DE89 3704 0044 0532 0130 00
英国 GB 22 GB29 NWBK 6016 1331 9268 19
法国 FR 27 FR14 2004 1010 0505 0001 3M02 606

MOD 97 校验算法原理

ISO 13616 使用的校验算法是 MOD 97-10。校验步骤如下:

  1. 去掉空格,全部转成大写。

  2. 把前 4 位(国家代码 + 校验位)移到字符串末尾。

  3. 把字母转成数字:A=10,B=11,……,Z=35。

  4. 把得到的整串数字对 97 取模,结果等于 1 则 IBAN 有效。

关键点:校验“通过”只代表格式和校验位正确,不代表这个账户真实存在。这一点在最终转账前必须和收款方或其银行确认。

用 JavaScript 实现

核心是把大数运算拆成逐位取模,避免整数溢出:

/**
 * 将 IBAN 转成数字串后对 97 取模(MOD 97-10)
 * 逐位处理以避免大数精度问题
 */
function mod97(str) {
  let remainder = 0;
  for (const ch of str.toUpperCase()) {
    const code = ch.charCodeAt(0);
    let digits;
    if (code >= 65 && code <= 90) {
      // A-Z -> 10-35,每个字母占两位
      const v = code - 55;
      digits = [Math.floor(v / 10), v % 10];
    } else {
      digits = [Number(ch)];
    }
    for (const d of digits) {
      remainder = (remainder * 10 + d) % 97;
    }
  }
  return remainder;
}

/**
 * 校验 IBAN:重排后取模,结果为 1 即有效
 */
function isValidIBAN(iban) {
  const cleaned = iban.replace(/\s+/g, '').toUpperCase();
  if (cleaned.length < 15 || cleaned.length > 34) return false;

  const reordered = cleaned.slice(4) + cleaned.slice(0, 4);
  return mod97(reordered) === 1;
}

// 测试
console.log(isValidIBAN('DE89 3704 0044 0532 0130 00')); // true
console.log(isValidIBAN('DE89 3704 0044 0532 0130 01')); // false(校验位不符)
console.log(isValidIBAN('GB29 NWBK 6016 1331 9268 19')); // true

严谨的校验还会按国家代码核对 IBAN 的固定长度(很多国家有规定长度,长度不对直接判无效),并限制国家代码必须存在于 ISO 3166 列表。生产环境建议两者都做。

快速验证与在线工具

自己写算法适合学习和集成,但日常临时核对一个 IBAN,或想快速查某家银行的 SWIFT/BIC 代码,用现成工具更快。我用的是 ibantool.com,它的特点正好契合这类敏感场景:

  • 免费、免注册,打开即用;

  • 校验 50+ 个国家的 IBAN,按 ISO 13616 检查格式、长度和 MOD 97 校验位;

  • 所有计算都在浏览器本地完成,你输入的 IBAN 不会上传到服务器——这点对财务信息尤其重要。

小结

IBAN 校验不难,核心就是 ISO 13616 + MOD 97 这一个算法。理解了结构、写得出代码,跨境业务里的“账号填没填对”就不再是玄学。唯一要记住的边界是:算法只能验证格式合法性,账户是否真实存在,永远要和收款方确认。

如果你也常处理国际汇款,或者手头有现成的账号列表想批量核对,可以先用在线工具验证思路,再把这套算法集成进你的系统。

posted @ 2026-08-30 15:48  小楼  阅读(1)  评论(0)    收藏  举报