IBAN explained: structure, check digits and test IBANs
An IBAN packs a country code, two check digits and a domestic account number into one string that banks across dozens of countries can read. This guide takes it apart, works through the mod-97 check by hand, gives tested validation code and explains what a valid IBAN does — and does not — prove.
Key takeaways
- An IBAN is a two-letter country code, two check digits and a country-specific BBAN, up to 34 characters in total.
- Validation is mechanical: check the length for the country, move the first four characters to the end, turn letters into numbers and test that the result mod 97 equals 1.
- A valid IBAN only proves the string is well formed. It says nothing about whether the account exists or who owns it.
- Use published example IBANs or a generator for tests, and never send a real payment to a generated IBAN.
On this page
If your product moves money between bank accounts — payouts, refunds by transfer, direct debits, invoicing — you will collect IBANs. They look intimidating, but they follow a small set of public rules, and validating one takes a dozen lines of code. Knowing those rules also tells you where validation stops and where the bank’s own checks have to take over.
What an IBAN is
The International Bank Account Number is defined by the ISO 13616 standard, first published in 1997 and most recently revised in 2020. It wraps each country’s existing domestic account number in a common envelope, so a bank in one country can recognize, route and sanity-check an account number from another without knowing every national format by heart. SWIFT acts as the registrar under ISO 13616 and publishes the IBAN registry, which lists the structure and length for every participating country.
IBANs are used across Europe — including the 41 countries of the Single Euro Payments Area (SEPA), where they are the standard account identifier for euro transfers and direct debits — and in many countries of the Middle East, North Africa, the Caribbean and Latin America. Several large economies, including the United States, Canada and Australia, do not use them.
The structure of an IBAN
Every IBAN has the same three parts. Here is the textbook British example, GB82 WEST 1234 5698 7654 32:
| Part | Example | What it is |
|---|---|---|
| Country code | GB | ISO 3166-1 alpha-2 code of the country where the account is held |
| Check digits | 82 | Two digits computed with ISO 7064 MOD 97-10 over the whole IBAN |
| BBAN | WEST12345698765432 | The Basic Bank Account Number: the domestic bank, branch and account identifiers in the country’s own layout, up to 30 characters |
Electronic and paper formats
In files, APIs and databases, an IBAN is written as one unbroken string of up to 34 uppercase letters and digits. On paper and on screens it is usually split into groups of four separated by spaces, as above, to make it easier to read aloud and copy. Your forms should accept both, strip the spaces, and store the electronic format.
Reading the BBAN
The BBAN is where countries differ. In the British example, WEST identifies the bank, 123456 is the sort code and 98765432 is the account number. A German BBAN is an eight-digit bank code followed by a ten-digit account number. Some countries embed their own national check digits inside the BBAN as well, which a strict validator can verify in addition to the IBAN check digits.
IBAN lengths by country
The length is fixed per country, so checking it is the cheapest validation you can run. These examples are taken from the IBAN registry’s published samples and all pass the check-digit test:
| Country | Length | BBAN layout | Example IBAN |
|---|---|---|---|
| Norway (NO) | 15 | bank 4 digits · account 6 · national check 1 | NO9386011117947 |
| Belgium (BE) | 16 | bank 3 digits · account 7 · national check 2 | BE68539007547034 |
| Netherlands (NL) | 18 | bank 4 letters · account 10 digits | NL91ABNA0417164300 |
| Switzerland (CH) | 21 | clearing number 5 digits · account 12 characters | CH9300762011623852957 |
| Germany (DE) | 22 | bank code (BLZ) 8 digits · account 10 | DE89370400440532013000 |
| United Kingdom (GB) | 22 | bank 4 letters · sort code 6 digits · account 8 | GB29NWBK60161331926819 |
| United Arab Emirates (AE) | 23 | bank 3 digits · account 16 | AE070331234567890123456 |
| Spain (ES) | 24 | bank 4 · branch 4 · national check 2 · account 10 | ES9121000418450200051332 |
| Saudi Arabia (SA) | 24 | bank 2 digits · account 18 characters | SA0380000000608010167519 |
| Turkey (TR) | 26 | bank 5 digits · reserved 1 · account 16 characters | TR330006100519786457841326 |
| France (FR) | 27 | bank 5 · branch 5 · account 11 characters · RIB key 2 | FR1420041010050500013M02606 |
| Italy (IT) | 27 | CIN letter · ABI 5 · CAB 5 · account 12 characters | IT60X0542811101000000123456 |
| Poland (PL) | 28 | bank and branch 8 digits · account 16 | PL61109010140000071219812874 |
| Brazil (BR) | 29 | bank 8 · branch 5 · account 10 · type 1 letter · owner 1 | BR1800360305000010009795493C1 |
| Malta (MT) | 31 | bank 4 letters · branch 5 digits · account 18 characters | MT84MALT011000012345MTLCAST001S |
Note how the layouts mix digits and letters. The Netherlands and the UK start the BBAN with a four-letter bank code, Italy begins with a check letter, and France allows letters inside the account number. A validator that expects digits only after the check digits will reject valid IBANs from those countries.
How the check digits work
The two check digits make the whole IBAN, read as one big number in a particular way, leave a remainder of exactly 1 when divided by 97. A single mistyped character or a swap of two neighboring characters almost always breaks that property, so the check catches the typing mistakes people actually make.
Validating an IBAN step by step
- Normalize. Remove spaces and convert to uppercase:
GB82WEST12345698765432. - Check the length for the country: GB IBANs have 22 characters.
- Move the first four characters to the end:
WEST12345698765432GB82. - Replace each letter with two digits, where A = 10, B = 11 … Z = 35. W becomes 32, E 14, S 28, T 29, G 16 and B 11, giving
3214282912345698765432161182. - Divide by 97. The remainder is 1, so the IBAN is valid. Any other remainder means it is not.
Doing it without big integers
That number has 28 digits, more than a 64-bit integer can hold. Languages with arbitrary-precision integers (Python, Java’s BigInteger, JavaScript’s BigInt) can compute it directly. Elsewhere, process the digits in pieces: take the first nine digits, reduce them mod 97, write the two-digit remainder in front of the next seven digits, and repeat.
| Step | Number | mod 97 |
|---|---|---|
| 1 | 321428291 | 70 |
| 2 | 702345698 | 29 |
| 3 | 297654321 | 24 |
| 4 | 2461182 | 1 |
The last remainder is 1, the same result as the direct calculation.
Calculating check digits for a new IBAN
To build an IBAN from a country code and a BBAN, put 00 in place of the check digits and run the same steps. For the German BBAN 370400440532013000: rearranged with zeros, the string is 370400440532013000DE00, which becomes 370400440532013000131400. That leaves a remainder of 9, and the check digits are 98 − 9 = 89 (padded to two digits when needed). The finished IBAN is DE89370400440532013000.
IBAN validation code
Both snippets accept the paper format with spaces, check the general shape, then run the mod-97 test. In production, also compare the length against a per-country table such as the one above.
Python
import re
def to_digits(s: str) -> str:
return ''.join(str(int(c, 36)) for c in s) # '0'-'9' stay, 'A' -> '10' ... 'Z' -> '35'
def iban_valid(iban: str) -> bool:
s = re.sub(r'\s+', '', iban).upper()
if not re.fullmatch(r'[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}', s):
return False
return int(to_digits(s[4:] + s[:4])) % 97 == 1
def iban_check_digits(country: str, bban: str) -> str:
return f'{98 - int(to_digits(bban + country + "00")) % 97:02d}'
print(iban_valid('GB82 WEST 1234 5698 7654 32')) # True
print(iban_check_digits('DE', '370400440532013000')) # 89JavaScript
function mod97(digits) {
let rem = 0;
for (let i = 0; i < digits.length; i += 7) {
rem = Number(String(rem) + digits.slice(i, i + 7)) % 97; // piecewise: no BigInt needed
}
return rem;
}
function toDigits(s) {
return s.replace(/[A-Z]/g, (c) => String(c.charCodeAt(0) - 55));
}
function ibanValid(input) {
const s = String(input).replace(/\s+/g, '').toUpperCase();
if (!/^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$/.test(s)) return false;
return mod97(toDigits(s.slice(4) + s.slice(0, 4))) === 1;
}
function ibanCheckDigits(country, bban) {
return String(98 - mod97(toDigits(bban + country + '00'))).padStart(2, '0');
}
console.log(ibanValid('GB82 WEST 1234 5698 7654 32')); // true
console.log(ibanCheckDigits('DE', '370400440532013000')); // '89'The {11,30} in the shape check reflects the shortest BBAN in use (Norway’s 11 characters) and the standard’s 30-character maximum. Our IBAN checker runs the full per-country length and format check and shows each step for any IBAN you paste in.
What a valid IBAN does — and does not — prove
Passing the checks tells you the string is well formed for its country and was very probably typed correctly. That is valuable: it stops most failed transfers caused by typos before they cost a returned-payment fee. It does not tell you:
- That the account exists. Anyone can compute valid check digits for any BBAN, which is exactly what an IBAN generator does.
- Who owns it. The IBAN carries no name. Name-matching services such as Confirmation of Payee in the UK and Verification of Payee in the EU compare the payee name with the account holder before a transfer is sent.
- That it can receive the payment. The account may be closed, blocked, or of a type that does not accept the currency or payment scheme you use.
Treat IBAN validation like the Luhn check for card numbers: a fast, local guard against typos, with the bank having the final word.
IBAN, BIC and SWIFT codes
People often confuse these identifiers, and forms that ask for the wrong one cause failed payments.
| Identifier | Standard | Identifies | Example |
|---|---|---|---|
| IBAN | ISO 13616 | One bank account | GB82WEST12345698765432 |
| BIC (“SWIFT code”) | ISO 9362 | A bank or branch, 8 or 11 characters | DEUTDEFF |
| BBAN / domestic number | National | The account inside its own country | WEST 123456 98765432 |
For euro transfers within SEPA, the IBAN is normally all you need; asking customers for a BIC there adds friction for no benefit. For international transfers outside SEPA, banks typically ask for both the IBAN (where the destination country uses one) and the receiving bank’s BIC.
Test IBANs for development
Real IBANs are personal data. Copying customers’ account details into a development database, a bug report or a test fixture creates the same kind of exposure that PCI DSS forbids for card numbers. For testing, use one of these instead:
- Registry examples such as those in the table above. They are published as samples for exactly this purpose and are widely recognized as test values.
- Generated IBANs. Our IBAN generator builds IBANs with the correct length, layout and check digits for many countries, so you can test per-country formatting and bulk imports.
- Payment provider test values. If you use a provider for SEPA Direct Debit or payouts, its sandbox documents specific IBANs that simulate success, failure and returns. Use those for end-to-end tests.
Never send money to a generated IBAN
A generated IBAN is random within a valid structure. In a live system a transfer to it either fails or, by chance, reaches a real person’s account. Keep generated IBANs in test environments only.
A short test plan
- Valid examples from several countries, with and without spaces and in lowercase.
- The same IBANs with one character changed and with two neighboring characters swapped (must fail).
- A valid IBAN with one character removed or added (must fail on length).
- IBANs with letters in the BBAN (Netherlands, UK, France, Italy) to make sure your validator does not assume digits.
- An unknown or non-IBAN country code, such as
US(must fail with a clear message).
Frequently asked questions
How many characters does an IBAN have?
It depends on the country, from 15 in Norway to more than 30 in a few countries, with 34 as the maximum the standard allows. Germany and the UK use 22, France and Italy 27.
What are the two digits after the country code?
They are check digits calculated with the ISO 7064 MOD 97-10 method over the whole IBAN. They let software detect typing mistakes before a payment is sent.
Does a valid IBAN mean the account exists?
No. A validator only confirms the length, the format and the check digits. Only the receiving bank knows whether the account is open and who holds it; name-checking services such as Confirmation of Payee in the UK and Verification of Payee in the EU address that separately.
What is the difference between an IBAN and a BIC or SWIFT code?
The IBAN identifies an individual account. The BIC (ISO 9362, often called a SWIFT code) identifies the bank. Within the SEPA area, the IBAN alone is normally enough for euro transfers.
Can I use a generated IBAN to receive money?
No. A generated IBAN has valid structure and check digits, but no bank opened the account. A transfer to it fails or, by chance, reaches someone else’s account, so use generated IBANs only as test data.
Does the United States use IBANs?
No. The US, Canada and Australia, among others, do not use IBANs. Payments to those countries use domestic routing and account numbers together with the bank’s BIC.
Sources
Tools used in this guide
Related guides
Written for developers, QA teams and merchants. Generated card numbers are test data: they are not real cards and cannot pay for anything.