Functional Weave
Code in TypeScript

validation.iban@1.0.0

README.md

2,748 bytes · view raw

# validation.iban

A VALID IBAN IS NOT AN EXISTING ACCOUNT. The checksum proves the string was
typed correctly; it says nothing about whether the account is open, whether the
bank exists, or whose name is on it. Paying the wrong person is almost always a
name mismatch rather than a checksum failure, so this belongs in front of a
Confirmation of Payee check, not instead of one.

THE CHECK: strip spaces, fold to upper case, move the first four characters to
the end, map A-Z to 10-35, and require the resulting decimal string to be 1
modulo 97. The expansion of a 34-character IBAN is up to 68 digits, which no
64-bit integer can hold, so all three implementations carry the remainder
forward one character at a time. A letter contributes two digits and so
multiplies the running remainder by 100; the largest intermediate value is 96 *
100 + 35 = 9635. Python could have used a big integer and Rust could not, so
Python uses the chunked form too - the point of the registry is that the three
languages run the same algorithm, not merely reach the same answer today.

THE LENGTH TABLE IS DATA, NOT CODE. data/iban-lengths.json maps each registered
country code to its exact IBAN length, and it is the second half of the
validation: mod-97-10 on its own accepts a correctly-checksummed string of any
length, so a truncated or padded account number can slip through it. SWIFT
publishes a new IBAN registry release roughly twice a year, adding countries and
occasionally changing a length. When that happens, publish a new version of this
capability's data. No application code changes.

Countries absent from the table are rejected, which is the correct answer for
the United States, Canada, Australia and everywhere else that never adopted
IBAN, and also the correct answer for a country added to the registry after this
data release - a false negative that a data update fixes, rather than a false
positive that nobody notices.

ACCEPTED INPUT: upper or lower case, with or without the conventional spaces
every four characters, including leading and trailing spaces. Nothing else is
stripped: hyphens, dots and non-breaking spaces make the value invalid rather
than being skipped, because they mean the value came from somewhere other than a
printed IBAN.

OUT OF SCOPE: the country-specific BBAN structure. The UK's IBAN embeds a
four-letter bank code, a six-digit sort code and an eight-digit account number,
and this capability does not check that inner shape, only the overall length and
the checksum. It also does not reject the reserved check digits 00, 01 and 99
explicitly; the mod-97 test already fails every such value.

Validators answer rather than throw: an unparseable value is not an exceptional
condition, it is the answer "no".