How IBAN Check Digits Work
Every IBAN includes two check digits that catch 99.9% of typing errors. They use a mathematical formula called MOD-97, first published in ISO 7064. Here's how it works.
The MOD-97 Algorithm
The check digits (positions 3-4 in every IBAN) are computed using the MOD-97 algorithm. Here is the step-by-step process:
Step 1: Rearrange the IBAN
Move the first four characters (country code + check digits) to the end of the string.
Example for GB29 NWBK 6016 1331 9268 19:
Original: GB29 NWBK 6016 1331 9268 19 Rearrange: NWBK 6016 1331 9268 19 GB29
Step 2: Convert Letters to Numbers
Replace each letter with its numeric value: A=10, B=11, ..., Z=35.
A=10, B=11, C=12, ..., Z=35 N β 23, W β 32, B β 11, K β 20, G β 16, B β 11
Step 3: Compute MOD-97
Interpret the resulting string as a huge integer and divide by 97. A valid IBAN always gives remainder 1.
NWBK60161331926819GB29 β (huge integer) mod 97 = 1 β
How Check Digits Are Generated
When a bank creates an IBAN, it:
- Starts with the country code + "00" + BBAN (domestic account details)
- Moves the first 4 chars to the end
- Converts letters to numbers
- Computes
remainder = big_number mod 97 - Check digits =
98 β remainder(zero-padded to 2 digits)
Why 97?
97 was chosen because:
- It's the largest two-digit prime number
- It catches 99.94% of single-digit typos and transposition errors
- The math works efficiently for numbers of any length
Computing MOD-97 in JavaScript
Since IBAN numeric strings can be 30+ digits (too large for JavaScript's Number type), we process in chunks:
function mod97(numStr) {
let remainder = numStr;
while (remainder.length > 2) {
let chunk = remainder.slice(0, 9); // 9 digits safely < MAX_SAFE_INTEGER
remainder = (parseInt(chunk, 10) % 97).toString() + remainder.slice(chunk.length);
}
return parseInt(remainder, 10) % 97;
}