Repository navigation
fix: check IBAN country code and length - #8
Merged
Merged
Conversation
isValidIban accepted any 15 to 34 character candidate with a valid mod-97 checksum. A random candidate passes the checksum 1 time in 97, so hex ids and other codes that start with two letters and two digits were still taken for IBANs now and then. A candidate must now also start with a country code that issues IBANs and have that country's length (compact form, spaces removed). The table has the 97 countries of the SWIFT IBAN registry and 27 countries that issue IBANs outside it, taken from ibantools 4.5.4 and iban 0.0.14; where the two disagree on a non-registry country, both lengths are accepted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E3AAifuwHuKGdoVpqZoQAo
pavish
marked this pull request as ready for review
November 5, 2026 11:30
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
isValidIbanaccepts any compact candidate of 15 to 34 characters (2 letters, 2 digits, 11 to 30 letters or digits) with a valid mod-97 checksum. A random candidate of that shape passes the checksum 1 time in 97, so upper-case hex ids and codes that start with two letters and two digits are still taken for IBANs now and then.A candidate must now also:
The check runs inside
isValidIban, before the checksum, so the existing prefix handling inreplaceIban(DE89 3704 … 00 BIC …) works as before.Country table (
src/iban-countries.ts):countrySpecsand iban 0.0.14 (the package behind@epilot/validators). The two agree on every registry length.Behaviour change:
Effect on hex ids
scrubon 200,000 random ids per form. Counts are ids changed by the IBAN pattern; the phone pattern is unchanged by this PR and listed separately.mainEXIT-LOOP-+ 32 hex, upper caseAD(Andorra, length 24) and pass the checksum by chance.IBAN_PATTERNis upper case only, so lower-case ids never matched it.Performance
mainagainst this PR, each variant in its own process, 5 processes each; per process the median of 5 runs. Node 22, one machine.mainmedian (range)scrub, 100k texts with an IBAN and BICscrub, 100k invalid IBAN-shaped codesscrub, 100k upper-case 32-hex idsscrub, 100k labels without candidateanonymizeResponse, 16k mixed strings (as inperformance.test.ts)Why it got faster: the country and length check costs one object lookup per candidate and runs before the mod-97 loop. Candidates that fail it skip the checksum, including the longer prefixes
replaceIbantries when an IBAN is followed by text (… 00 BIC COBADEFFXXX). That's why text with an IBAN and invalid IBAN-shaped codes got faster.The other rows are within the range of the runs. Memory was not measured.
Test plan
npm run lint,npm test(99 existing + 3 new tests),npm run buildvalue-detection.test.ts:🤖 Generated with Claude Code
https://claude.ai/code/session_01E3AAifuwHuKGdoVpqZoQAo