IBAN 校驗與解析

在瀏覽器本地校驗國際銀行賬號:國家程式碼、註冊長度、ISO 7064 MOD 97-10 校驗位,並輸出結構拆解與列印格式。

這個賬號在結構上成立嗎? 貼上 IBAN,帶不帶空格都可以。校驗全程在瀏覽器本地完成:先比對 SWIFT 登錄檔中的國家程式碼,再核對總長度,最後計算 ISO 7064 MOD 97-10 校驗位。

國家
校驗位
BBAN
長度

IBAN 校驗到底在做什麼

本國賬號外面套了一層殼

IBAN 並不是一種全新的賬號,它就是原有的國內賬號(稱為 BBAN),在前面拼上四個字元:兩位 ISO 3166 國家程式碼和兩位校驗位。這四個字元之後的內容,完全沿用各國銀行體系原本的編號方式——這正是長度差異如此之大的原因。挪威的 IBAN 是 15 位,馬耳他的是 31 位,兩者都完全正確。

這種長度差異構成了第一道真正的校驗,也是最常被跳過的一步。每個國家都在 SWIFT 註冊了確切的總長度,這是固定值而非上限。德國 IBAN 永遠是 22 位。如果你收到一個 DE 開頭的 21 位字串,那無論校驗位算不算得過都是錯的——因為讓字串變短的錯誤,校驗位根本"看不到"缺失的那個字元。先查國家長度還有一個好處:給出的錯誤提示遠比一句籠統的"校驗失敗"有用。

MOD 97-10 校驗位

校驗演算法來自 ISO 7064,思路相當優雅:把前四個字元挪到末尾,把每個字母替換成數字(A 為 10,一直到 Z 為 35),然後把整串當作一個巨大的整數來讀。如果這個整數除以 97 的餘數恰好是 1,IBAN 就通過。

麻煩在於這個數遠超任何語言的原生整數型別,常常有八十位以上。實現上不必引入大數庫,而是分段取模:從左到右遍歷字串,每處理一位就只保留對 97 取模後的執行值。由於模運算對逐位構造具有分配性,最終餘數與用完整數字計算的結果完全一致,而代價只是一次遍歷、零額外記憶體分配。本工具正是這麼做的。

之所以選擇 MOD 97-10,是因為對於僅僅兩個校驗字元來說它異常強健:能檢出所有單字元替換、所有相鄰兩字元換位,以及絕大多數更長的亂序。它檢測不到的錯誤形態非常罕見,剩餘風險主要來自"賬號本身並不存在"這一層。

校驗通過不代表什麼

結構有效不等於賬戶存在。一個校驗位正確的 IBAN,可能指向一個已銷戶的賬戶、一個從未開立的賬戶,或一家早已被合併掉的銀行。唯一能確認錢會到賬的方式是發起轉賬,或使用銀行提供的驗證服務。請把校驗當作錄入環節的錯別字攔截,而不是收款方真實性的證明。

格式同樣需要注意。登錄檔定義的電子格式是不含空格的連續字串,支付檔案裡傳輸、資料庫裡儲存都必須用這一種。每四位一組的形式只用於紙面列印,目的是幫人準確抄寫長串數字。正確做法是:錄入時歸一化,儲存用無空格形式,僅在展示時再把空格加回去。

開源說明:使用原生 JavaScript 實現,不依賴第三方庫。

常見問題

校驗位正確是否意味著賬戶存在?
不是。校驗位只能證明字串內部自洽,沒有輸錯或換位。它背後的賬戶可能已經銷戶,也可能從未開立。只有收款銀行才能確認一個 IBAN 是否有效在用。
為什麼 IBAN 長度各不相同?
因為前四位之後的部分就是各國原有的國內賬號,而這些編號在 IBAN 出現之前很久就已在各國內部標準化了。每個國家向 SWIFT 註冊了自己的固定長度,從挪威的 15 位到聖露西亞的 32 位不等。
儲存 IBAN 時要不要帶空格?
不要。應儲存電子格式,即不含空格和標點的連續字串,支付系統預期的也是這一種。每四位分組只是列印習慣,渲染時再加、錄入時去掉即可。
BBAN 部分是什麼?
即基本銀行賬號,指國家程式碼和校驗位之後的全部內容。它的內部結構因國家而異,通常編碼了銀行標識、分行程式碼和賬號,有時還帶有本國自己的校驗位。
我的 IBAN 會被髮送到伺服器嗎?
不會。長度查表和 MOD 97-10 計算都在瀏覽器內完成,頁面不會對你的輸入發起任何網路請求。斷網狀態下工具照常工作。
位數明明正確,為什麼還是校驗失敗?
幾乎總是有一個字元輸錯或換位了。MOD 97-10 能檢出所有單字元錯誤和相鄰換位,所以在長度正確的前提下失敗,說明必有一個字元不對。請重新核對原件,尤其注意容易混淆的 0 與 O、1 與 I。