Why ISO 7064 mod-97 was chosen over a simple checksum
An IBAN like FR76 3000 3035 4096 6001 4860 T20 looks arbitrary but every character is engineered. The two characters at positions 3–4 are check digits, and the algorithm used to compute them — ISO 7064 mod-97 — was specifically chosen over Luhn, over CRCs, over simple sum-of-digits. Here is why, and what it does (and does not) protect you against.
The problem ISO 13616 needed to solve
Cross-border bank transfers in the 1990s were a mess of national formats. The European Committee for Banking Standards needed an identifier that would (1) detect typing errors at the point of entry, before the wire was sent; (2) work across 70+ countries with widely varying account-number structures (length 14–34 characters, alphanumeric in some, numeric-only in others); (3) not require calling the bank for a syntactic check. ISO 13616 defined the structure; ISO 7064 defined the check-digit algorithm.
Why mod-97 specifically
97 is the largest prime under 100. That matters because the validity check is IBAN_as_integer mod 97 = 1. A prime modulus guarantees a uniform distribution of checksum values across all possible inputs, which minimises false positives. 97 is also large enough that the probability of a random IBAN passing the check by accident is 1/97 ≈ 1.03%. Critically: mod-97 detects every single-digit error and every adjacent-digit swap exhaustively — both errors that dominate human transcription mistakes.
Why not Luhn (the credit-card algorithm)?
Luhn was designed for 13–19 digit credit-card numbers. It catches single-digit errors and most adjacent-digit transpositions but misses roughly 2% of two-digit transpositions (specifically those that produce the same Luhn sum). For a 4-character bank routing slip, Luhn is fine. For a 22–34 character IBAN, mod-97 is dramatically more error-tolerant per character spent on checking.
Why not a CRC?
Cyclic redundancy checks excel at burst-error detection in machine-to-machine transmission. They are overkill (and wasteful of digit-budget) for human transcription. Mod-97 fits the check into exactly two decimal digits; a CRC-8 would consume the same two digits but provide weaker coverage of the error patterns humans actually make (transpositions, single-digit slips). For paper-to-screen typing, mod-97 wins.
What mod-97 does NOT protect against
It catches transcription errors. It does not verify that the bank code, branch code, or account number actually exists at a real bank. It does not check that the account is open, in good standing, or able to receive funds. Those answers come from the bank or from a SWIFT lookup — out of scope for ISO 13616. A valid IBAN is one that could be a real account, not one that is.
Takeaway: Mod-97 is the right primitive for a human-typed identifier where transcription errors dominate over malicious modification. The validator on this page implements the standard exactly: rearrange the IBAN (country code + check digits to the end), convert letters to numbers (A = 10, B = 11, ..., Z = 35), interpret the result as one large integer, check it modulo 97 equals 1. That is the entire algorithm. No proprietary magic, no per-country variants.
Sources: SWIFT IBAN Registry (ISO 13616) · ISO 7064 standard.