fix(finance): isin() actually validates the check digit#468
Open
Jordan-Bourillot wants to merge 1 commit into
Open
fix(finance): isin() actually validates the check digit#468Jordan-Bourillot wants to merge 1 commit into
Jordan-Bourillot wants to merge 1 commit into
Conversation
_isin_checksum never accumulated into `check` (the accumulation line
present in _cusip_checksum was missing), and the per-character loop it
copied is not the ISIN scheme anyway. `check` stayed 0, so isin()
returned True for every 12-character string -- e.g. isin('US0378331004')
(wrong check digit) and isin('XX0000000000').
Reimplement with the documented ISIN algorithm: expand letters to digits
(A=10..Z=35) and run Luhn over the result. Verified against real ISINs
(US0378331005, AU0000XVGZA3, GB0002634946).
The existing 'valid' fixture 'JP000K0VF054' was itself invalid (its
correct check digit is 5) -- corrected to 'JP000K0VF055'. Added a
wrong-check-digit case to the invalid fixtures and a valid example to
the docstring.
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
isin()accepted any 12-character string — the check digit was never actually verified.Root cause
_isin_checksuminitialisedcheck = 0and then never updated it inside the loop (thecheck += (val // 10) + (val % 10)line that exists in_cusip_checksumwas missing). It also reused the per-character CUSIP scheme, which is not the ISIN algorithm. Socheckstayed0and(check % 10) == 0was always true.Fix
Reimplement with the documented ISIN scheme: expand letters to digits (A=10 … Z=35) and run the Luhn algorithm over the result. Verified against real ISINs (
US0378331005,AU0000XVGZA3,GB0002634946, …).Tests
JP000K0VF054, was itself invalid — its correct check digit is5, and only the broken checksum let it pass. Corrected toJP000K0VF055.US0378331004) to the invalid fixtures, plus a valid example in the docstring.The full test suite passes and
ruffis clean.