Every IBAN includes a built-in error-detection mechanism based on the MOD-97 algorithm, as specified by ISO 7064. This algorithm catches over 99% of transcription errors — including mistyped digits, transposed characters, and missing or extra characters — before a payment is ever submitted to the banking network. This guide provides a complete technical explanation of how the IBAN validation algorithm works, walks through a real example step by step, and covers the edge cases and implementation details that matter for developers and anyone who works with IBANs regularly. For background on IBANs themselves, see our guide on what an IBAN is and how it works.
Before diving into the algorithm, it helps to understand what you are validating. Every IBAN follows the same high-level structure, regardless of country:
The total length ranges from 15 characters (Norway) to 34 characters (Saint Lucia). The country code tells you which country's banking system the account belongs to. The check digits provide the error-detection capability. The BBAN contains the domestic bank details — bank code, branch code, and account number — in a format defined by each country's national banking authority.
The validation algorithm operates on the entire IBAN as a single unit. It does not care about the internal structure of the BBAN; it treats the whole string as input and produces a simple pass/fail result based on the MOD-97 remainder.
The core of IBAN validation is a four-step process that converts the alphanumeric IBAN into a large integer and checks whether it is divisible by 97 with a remainder of 1. Here are the steps:
This algorithm is defined by ISO 13616 (which governs the IBAN structure) and uses the MOD-97-10 check character system from ISO 7064. The reason the valid remainder is 1 (not 0) is by design: it ensures that check digits of 00 and 01 are impossible, which provides an additional sanity check.
Let's validate the British IBAN GB29 NWBK 6016 1331 9268 19 step by step.
Step 1: Move the first four characters to the end
The original IBAN (without spaces) is GB29NWBK60161331926819. Move GB29 to the end:
NWBK60161331926819GB29
Step 2: Replace letters with numbers
Convert each letter using the mapping (A = 10, B = 11, ... Z = 35):
The rearranged string NWBK60161331926819GB29 becomes:
2332112060161331926819161129
Step 3: Compute the remainder (MOD 97)
The numeric string is 28 digits long — far too large for standard integer arithmetic. We use the chunking method, processing 9 digits at a time:
233211206 MOD 97 = 76760161331 MOD 97 = 20209268191 MOD 97 = 686816112 MOD 97 = 44449 MOD 97 = 1Step 4: Check the result
The final remainder is 1. The IBAN GB29 NWBK 6016 1331 9268 19 is valid.
If any single character had been mistyped — for example, changing the 9 in the check digits to an 8 (GB28) — the final remainder would not be 1, and the validation would fail. This is the power of the MOD-97 algorithm: it detects the error before any money moves.
The following table shows the numeric value assigned to each letter during Step 2 of the algorithm. This mapping is defined by ISO 13616 and follows a simple rule: each letter's value equals its position in the alphabet plus 9 (A is the 1st letter, so A = 1 + 9 = 10).
| Letter | Value | Letter | Value | Letter | Value |
|---|---|---|---|---|---|
| A | 10 | J | 19 | S | 28 |
| B | 11 | K | 20 | T | 29 |
| C | 12 | L | 21 | U | 30 |
| D | 13 | M | 22 | V | 31 |
| E | 14 | N | 23 | W | 32 |
| F | 15 | O | 24 | X | 33 |
| G | 16 | P | 25 | Y | 34 |
| H | 17 | Q | 26 | Z | 35 |
| I | 18 | R | 27 |
The conversion is case-insensitive — lowercase letters should be converted to uppercase first. Digits (0–9) pass through unchanged and are not substituted.
The choice of 97 as the modulus is not arbitrary. It was selected for specific mathematical properties that maximize error detection in alphanumeric strings:
The combination of these properties makes MOD-97 one of the most effective check-digit systems in use for financial identifiers. The designers of the IBAN standard specifically selected it because the cost of a misdirected international payment far exceeds the minor increase in computational complexity compared to simpler alternatives.
The MOD-97 algorithm validates the IBAN as a whole, but it does not examine the internal structure of the BBAN. A comprehensive validation system also checks country-specific rules:
A robust IBAN validator performs all of these checks in sequence: country code recognition, length verification, character pattern matching, MOD-97 checksum, and (optionally) national check-digit validation and bank code lookup.
Several edge cases deserve attention when implementing or reasoning about IBAN validation:
Leading zeros in check digits
Check digits range from 02 to 98. Single-digit values (2 through 9) are left-padded with a zero, so you will see IBANs with check digits like 06 or 03. Implementations must preserve these leading zeros as characters, not strip them as would happen with numeric parsing. An IBAN with check digits 00 or 01 is always invalid — the formula 98 – (value MOD 97) can never produce these values.
Maximum-length IBANs
The ISO 13616 standard allows IBANs up to 34 characters. Saint Lucia (LC) uses the longest registered format at 32 characters, while Seychelles (SC) also uses 31 characters. When these IBANs are converted to their numeric form during MOD-97 calculation, the resulting number can exceed 40 digits — well beyond the range of any standard integer type. This is why the chunking technique (described below) is essential for any practical implementation.
Spaces and formatting
IBANs are often printed in groups of four characters for readability (e.g., GB29 NWBK 6016 1331 9268 19), but the electronic format contains no spaces. Before running the MOD-97 algorithm, all spaces, hyphens, and other non-alphanumeric characters must be stripped. The algorithm operates on the raw alphanumeric string only.
Case sensitivity
The IBAN standard uses uppercase letters. However, validators should accept lowercase input and convert to uppercase before processing. A user typing gb29nwbk60161331926819 should get the same result as GB29NWBK60161331926819. The letter-to-number conversion is defined for uppercase letters only, so normalization must happen first.
The numeric string produced by Step 2 can easily exceed 30 digits, which overflows standard 32-bit and 64-bit integer types. The standard solution is the chunking technique: instead of computing MOD 97 on the entire number at once, you process it in segments of up to 9 digits (which safely fits in a 32-bit integer) or 16 digits (for 64-bit), carrying the remainder forward.
Pseudocode: MOD-97 with chunking
function mod97(numericString):
remainder = 0
for i = 0 to length(numericString) step 7:
chunk = toString(remainder) + substring(numericString, i, i+7)
remainder = toInteger(chunk) MOD 97
return remainder
The chunk size of 7 digits is conservative and works with 32-bit integers (the maximum intermediate value is a 9-digit number when the remainder is prepended, which fits within 2^31 – 1 = 2,147,483,647). Languages with 64-bit integers can use larger chunks for fewer iterations. Languages with native big-integer support (such as Python or JavaScript's BigInt) can skip chunking entirely and compute the modulus directly on the full number.
Here is the complete validation flow in pseudocode:
function validateIBAN(iban):
iban = removeSpaces(toUpperCase(iban))
if not matchesPattern(iban, "^[A-Z]{2}[0-9]{2}[A-Z0-9]+$"):
return false
if length(iban) != expectedLength(countryCode(iban)):
return false
rearranged = substring(iban, 4) + substring(iban, 0, 4)
numeric = replaceLettersWithNumbers(rearranged)
return mod97(numeric) == 1
For a practical guide to implementing this in real code, see our guide on how to validate bank details in code.
It is important to understand the limits of MOD-97 validation:
MOD-97 validation is a necessary first step, but it is not sufficient on its own. For high-value transfers, consider using confirmation-of-payee services (where available) to verify the account holder's name before sending money.
76, but the rest of their structure would be entirely different. Within the same country, two IBANs with the same check digits will always have different BBANs, so there is no risk of confusion. The check digits are not unique identifiers — they are error-detection codes specific to the IBAN they belong to.You do not need to run this algorithm by hand. Paste any IBAN into our free IBAN validator and it will run the full validation pipeline automatically: country code check, length verification, character pattern matching, MOD-97 checksum, and a detailed breakdown of the bank and account details encoded in the number. All processing runs entirely in your browser — no data is sent to any server.
Back to all guides.