How to Validate an IBAN (MOD-97 Check Digit, Explained)
You typed your IBAN, hit send, and the bank threw it straight back: invalid IBAN. The number looks exactly right — same letters, same digits you copied off the invoice — but the transfer won't go through. Before you blame the bank, know this: every IBAN carries a built-in self-check, and it just did

You typed your IBAN, hit send, and the bank threw it straight back: invalid IBAN. The number looks exactly right — same letters, same digits you copied off the invoice — but the transfer won't go through. Before you blame the bank, know this: every IBAN carries a built-in self-check, and it just did its job. Those two digits right after the country code are a checksum whose whole purpose is to catch a single typo or two swapped characters before your money moves to the wrong account. If you just need the payment to work, the fix is usually one mistyped character. If you're a developer wiring up validation, here's exactly how the MOD-97 algorithm does it. An IBAN is a country code, two check digits, then the BBAN — your domestic bank and account number. Those two check digits (positions 3 and 4) aren't part of your account. They're computed from the rest of the number using an algorithm called MOD-97, formally ISO 7064, mod 97-10. To validate an IBAN, you run the same math and confirm the result comes out to exactly 1. If it doesn't, something in the number is wrong. One caveat worth stating up front: passing MOD-97 only proves the number is internally consistent and the correct length. It does not confirm that the bank, branch, or account actually exists or is open. That requires a separate bank-directory or account-verification lookup — not the check-digit arithmetic. Normalize. Strip spaces and uppercase every letter. Check the length matches the fixed length for the country code (Germany is 22, UK 22, France 27, Norway 15, Malta 31). Rotate. Move the first four characters — country code plus check digits — from the front to the back. Letters to numbers. Replace each letter with two digits: A=10, B=11, … Z=35 (that's ord(L) - 55). Digits stay as they are. You now have one long numeric string. Mod 97. Read that string as a single huge integer and take its remainder modulo 97. It's far bigger than a 64-bit int, so use a bignum, or compute the remainder piecewise, left to right. Decide. A remainder of 1 means valid. Anything else means the number is corrupted. Take DE89370400440532013000 (Germany, so it must be 22 characters — it is). Rotate: move DE89 to the end → 370400440532013000DE89. Convert letters: D=13, E=14, so the tail DE89 becomes 131489. The full numeric string is 370400440532013000131489. Mod 97: as one big integer, 370400440532013000131489 mod 97 = 1. No bignum? Do it in chunks, prefixing each running remainder onto the next digits: 370400440 mod 97 = 23 235320130 mod 97 = 70 (the previous 23 in front of the next digits 5320130) 700013148 mod 97 = 38 389 mod 97 = 1 Both roads land on 1, so DE89370400440532013000 is valid. import re def validate_iban(iban: str) -> bool: iban = re.sub(r"[^A-Za-z0-9]", "", iban).upper() rearranged = iban[4:] + iban[:4] digits = "".join( str(ord(ch) - 55) if ch.isalpha() else ch for ch in rearranged ) return int(digits) % 97 == 1 print(validate_iban("DE89370400440532013000")) # True Python integers are arbitrary-precision, so the bignum path just works — no chunking needed. The re.sub also strips any stray spaces or punctuation left over from a copy-paste, so "DE89 3704 0044 0532 0130 00" validates too. For production, add a per-country length check before this test. Invisible junk from copy-paste. Leading or trailing spaces, non-breaking spaces, soft hyphens, and line breaks pasted out of a PDF or email survive the copy and break validation. Stripping plain spaces isn't always enough — strip anything that isn't A-Z or 0-9. O/0 and I/1/l confusion. Reading an IBAN off a printed statement, people type the letter O for zero, or capital I / lowercase l for the digit 1. One wrong character flips the remainder off 1 — exactly what MOD-97 is built to catch. A wrong length or a mistyped country code (DR for DE) fails the same way. Don't want to run the arithmetic? Paste the number into the IBAN checker, which validates the MOD-97 checksum and the per-country length right in your browser. Need to do this at scale — cleaning a payee list, or checking form input server-side? The JSON API takes up to 100 IBANs per call and also handles GTIN, EU VAT, VIN, ISIN, and more. Same input, same output, no AI guessing.
Key Takeaways
- •You typed your IBAN, hit send, and the bank threw it straight back: invalid IBAN
- •This story was reported by Dev.to, covering developments in the dev space.
- •AI advancements continue to reshape industries — read the full article on Dev.to for complete coverage.
📖 Continue reading the full article:
Read Full Article on Dev.to →


