FA-72381 / Check-digit algorithms / Open access
ISIN country prefix accepts a digit · case 01
Identifiers without an alphabetic country code are checksummed as if they were ISINs.
ROOT CAUSE
The alphabetic test on the two-character country code was dropped.
VERIFIED REPAIR
Require both leading characters to be uppercase letters.
Unsuccessful approach: Checking only the first character still admits a digit in the second country position.
Case contract
Input a 12-character ISIN: two uppercase ASCII letters (country), nine uppercase alphanumerics, one check digit; anything else is "malformed". Letters expand to two digits (A=10 .. Z=35), then Luhn doubling starts at the rightmost digit of the expanded 11-character payload. Return [computed check digit, whether it matches].
Why this case matters
Securities settlement systems reject ISINs whose check digit does not match before routing trades.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(s):
if len(s) != 12 or not s.isascii() or not s[:2].isupper():
return 'malformed'
if not s[2:11].isalnum() or s[2:11] != s[2:11].upper() or not s[11].isdigit():
return 'malformed'
digits = ''
for ch in s[:11]:
digits += ch if ch.isdigit() else str(ord(ch) - 55)
total = 0
for i, ch in enumerate(reversed(digits)):
d = int(ch)
if i % 2 == 0:
d *= 2
if d > 9:
d -= 9
total += d
check = (10 - total % 10) % 10
return [check, check == int(s[11])]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression ["1S0378331005"]', ['1S0378331005'], 'malformed'], ['regression ["U10378331005"]', ['U10378331005'], 'malformed'], ['control ["US4V5PGS4IX8"]', ['US4V5PGS4IX8'], [0, False]], ['control ["GBOV8F5J6090"]', ['GBOV8F5J6090'], [7, False]], ['control ["DEC85GG2TSS1"]', ['DEC85GG2TSS1'], [4, False]], ['control ["JPFWKDL124I1"]', ['JPFWKDL124I1'], [1, True]], ['control ["CHXVXSVIT016"]', ['CHXVXSVIT016'], [1, False]], ['control ["FRLWNIYHPT37"]', ['FRLWNIYHPT37'], [5, False]]], [['regression ["U10378331005"]', ['U10378331005'], 'malformed'], ['regression ["1S0378331005"]', ['1S0378331005'], 'malformed'], ['control ["FRLWNIYHPT37"]', ['FRLWNIYHPT37'], [5, False]], ['control ["XS0K4JDSXBN1"]', ['XS0K4JDSXBN1'], [4, False]], ['control ["NL5BVKR8BB60"]', ['NL5BVKR8BB60'], [3, False]], ['control ["AUKWRNHD2XR3"]', ['AUKWRNHD2XR3'], [8, False]], ['control ["CA3CKMM2IAN8"]', ['CA3CKMM2IAN8'], [0, False]], ['control ["US6754047769"]', ['US6754047769'], [8, False]]], [['regression ["1S0378331005"]', ['1S0378331005'], 'malformed'], ['regression ["U10378331005"]', ['U10378331005'], 'malformed'], ['control ["US6754047769"]', ['US6754047769'], [8, False]], ['control ["IE9141151847"]', ['IE9141151847'], [0, False]], ['control ["LU7763909076"]', ['LU7763909076'], [8, False]], ['control ["KY3791880781"]', ['KY3791880781'], [4, False]], ['control ["BM9170095145"]', ['BM9170095145'], [7, False]], ['control ["US0378331005"]', ['US0378331005'], [5, True]]], [['regression ["U10378331005"]', ['U10378331005'], 'malformed'], ['regression ["1S0378331005"]', ['1S0378331005'], 'malformed'], ['control ["US0378331005"]', ['US0378331005'], [5, True]], ['control ["US5949181045"]', ['US5949181045'], [5, True]], ['control ["GB0002634946"]', ['GB0002634946'], [6, True]], ['control ["AU0000XVGZA3"]', ['AU0000XVGZA3'], [3, True]], ['control ["DE000BAY0017"]', ['DE000BAY0017'], [7, True]], ['control ["US037833100"]', ['US037833100'], 'malformed']], [['regression ["1S0378331005"]', ['1S0378331005'], 'malformed'], ['regression ["U10378331005"]', ['U10378331005'], 'malformed'], ['control ["US037833100"]', ['US037833100'], 'malformed'], ['control ["us0378331005"]', ['us0378331005'], 'malformed'], ['control ["US03783310a5"]', ['US03783310a5'], 'malformed'], ['control ["12Q037833100"]', ['12Q037833100'], 'malformed'], ['control ["XS2021832634"]', ['XS2021832634'], [4, True]], ['control ["US38259P5089"]', ['US38259P5089'], [9, True]]]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression ["1S0378331005"] | [0, False] | malformed | Failed |
| regression ["U10378331005"] | [9, False] | malformed | Failed |
| control ["US4V5PGS4IX8"] | [0, False] | [0, False] | Passed |
| control ["GBOV8F5J6090"] | [7, False] | [7, False] | Passed |
| control ["DEC85GG2TSS1"] | [4, False] | [4, False] | Passed |
| control ["JPFWKDL124I1"] | [1, True] | [1, True] | Passed |
| control ["CHXVXSVIT016"] | [1, False] | [1, False] | Passed |
| control ["FRLWNIYHPT37"] | [5, False] | [5, False] | Passed |
SHA-256 / 06ea00a8ea8828b11c5c36aa44b1a10bed5dff1082d7b3382049049b94d9f6b6
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(s):
if len(s) != 12 or not s.isascii() or not s[0].isalpha() or not s[0].isupper():
return 'malformed'
if not s[2:11].isalnum() or s[2:11] != s[2:11].upper() or not s[11].isdigit():
return 'malformed'
digits = ''
for ch in s[:11]:
digits += ch if ch.isdigit() else str(ord(ch) - 55)
total = 0
for i, ch in enumerate(reversed(digits)):
d = int(ch)
if i % 2 == 0:
d *= 2
if d > 9:
d -= 9
total += d
check = (10 - total % 10) % 10
return [check, check == int(s[11])]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression ["1S0378331005"]', ['1S0378331005'], 'malformed'], ['regression ["U10378331005"]', ['U10378331005'], 'malformed'], ['control ["US4V5PGS4IX8"]', ['US4V5PGS4IX8'], [0, False]], ['control ["GBOV8F5J6090"]', ['GBOV8F5J6090'], [7, False]], ['control ["DEC85GG2TSS1"]', ['DEC85GG2TSS1'], [4, False]], ['control ["JPFWKDL124I1"]', ['JPFWKDL124I1'], [1, True]], ['control ["CHXVXSVIT016"]', ['CHXVXSVIT016'], [1, False]], ['control ["FRLWNIYHPT37"]', ['FRLWNIYHPT37'], [5, False]]], [['regression ["U10378331005"]', ['U10378331005'], 'malformed'], ['regression ["1S0378331005"]', ['1S0378331005'], 'malformed'], ['control ["FRLWNIYHPT37"]', ['FRLWNIYHPT37'], [5, False]], ['control ["XS0K4JDSXBN1"]', ['XS0K4JDSXBN1'], [4, False]], ['control ["NL5BVKR8BB60"]', ['NL5BVKR8BB60'], [3, False]], ['control ["AUKWRNHD2XR3"]', ['AUKWRNHD2XR3'], [8, False]], ['control ["CA3CKMM2IAN8"]', ['CA3CKMM2IAN8'], [0, False]], ['control ["US6754047769"]', ['US6754047769'], [8, False]]], [['regression ["1S0378331005"]', ['1S0378331005'], 'malformed'], ['regression ["U10378331005"]', ['U10378331005'], 'malformed'], ['control ["US6754047769"]', ['US6754047769'], [8, False]], ['control ["IE9141151847"]', ['IE9141151847'], [0, False]], ['control ["LU7763909076"]', ['LU7763909076'], [8, False]], ['control ["KY3791880781"]', ['KY3791880781'], [4, False]], ['control ["BM9170095145"]', ['BM9170095145'], [7, False]], ['control ["US0378331005"]', ['US0378331005'], [5, True]]], [['regression ["U10378331005"]', ['U10378331005'], 'malformed'], ['regression ["1S0378331005"]', ['1S0378331005'], 'malformed'], ['control ["US0378331005"]', ['US0378331005'], [5, True]], ['control ["US5949181045"]', ['US5949181045'], [5, True]], ['control ["GB0002634946"]', ['GB0002634946'], [6, True]], ['control ["AU0000XVGZA3"]', ['AU0000XVGZA3'], [3, True]], ['control ["DE000BAY0017"]', ['DE000BAY0017'], [7, True]], ['control ["US037833100"]', ['US037833100'], 'malformed']], [['regression ["1S0378331005"]', ['1S0378331005'], 'malformed'], ['regression ["U10378331005"]', ['U10378331005'], 'malformed'], ['control ["US037833100"]', ['US037833100'], 'malformed'], ['control ["us0378331005"]', ['us0378331005'], 'malformed'], ['control ["US03783310a5"]', ['US03783310a5'], 'malformed'], ['control ["12Q037833100"]', ['12Q037833100'], 'malformed'], ['control ["XS2021832634"]', ['XS2021832634'], [4, True]], ['control ["US38259P5089"]', ['US38259P5089'], [9, True]]]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression ["1S0378331005"] | malformed | malformed | Passed |
| regression ["U10378331005"] | [9, False] | malformed | Failed |
| control ["US4V5PGS4IX8"] | [0, False] | [0, False] | Passed |
| control ["GBOV8F5J6090"] | [7, False] | [7, False] | Passed |
| control ["DEC85GG2TSS1"] | [4, False] | [4, False] | Passed |
| control ["JPFWKDL124I1"] | [1, True] | [1, True] | Passed |
| control ["CHXVXSVIT016"] | [1, False] | [1, False] | Passed |
| control ["FRLWNIYHPT37"] | [5, False] | [5, False] | Passed |
SHA-256 / 90e3b2fb9245afc7fe34d7339428e8813c8e1e9f64b85d140cd6dc33f9389495
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(s):
if len(s) != 12 or not s.isascii() or not s[:2].isalpha() or not s[:2].isupper():
return 'malformed'
if not s[2:11].isalnum() or s[2:11] != s[2:11].upper() or not s[11].isdigit():
return 'malformed'
digits = ''
for ch in s[:11]:
digits += ch if ch.isdigit() else str(ord(ch) - 55)
total = 0
for i, ch in enumerate(reversed(digits)):
d = int(ch)
if i % 2 == 0:
d *= 2
if d > 9:
d -= 9
total += d
check = (10 - total % 10) % 10
return [check, check == int(s[11])]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression ["1S0378331005"]', ['1S0378331005'], 'malformed'], ['regression ["U10378331005"]', ['U10378331005'], 'malformed'], ['control ["US4V5PGS4IX8"]', ['US4V5PGS4IX8'], [0, False]], ['control ["GBOV8F5J6090"]', ['GBOV8F5J6090'], [7, False]], ['control ["DEC85GG2TSS1"]', ['DEC85GG2TSS1'], [4, False]], ['control ["JPFWKDL124I1"]', ['JPFWKDL124I1'], [1, True]], ['control ["CHXVXSVIT016"]', ['CHXVXSVIT016'], [1, False]], ['control ["FRLWNIYHPT37"]', ['FRLWNIYHPT37'], [5, False]]], [['regression ["U10378331005"]', ['U10378331005'], 'malformed'], ['regression ["1S0378331005"]', ['1S0378331005'], 'malformed'], ['control ["FRLWNIYHPT37"]', ['FRLWNIYHPT37'], [5, False]], ['control ["XS0K4JDSXBN1"]', ['XS0K4JDSXBN1'], [4, False]], ['control ["NL5BVKR8BB60"]', ['NL5BVKR8BB60'], [3, False]], ['control ["AUKWRNHD2XR3"]', ['AUKWRNHD2XR3'], [8, False]], ['control ["CA3CKMM2IAN8"]', ['CA3CKMM2IAN8'], [0, False]], ['control ["US6754047769"]', ['US6754047769'], [8, False]]], [['regression ["1S0378331005"]', ['1S0378331005'], 'malformed'], ['regression ["U10378331005"]', ['U10378331005'], 'malformed'], ['control ["US6754047769"]', ['US6754047769'], [8, False]], ['control ["IE9141151847"]', ['IE9141151847'], [0, False]], ['control ["LU7763909076"]', ['LU7763909076'], [8, False]], ['control ["KY3791880781"]', ['KY3791880781'], [4, False]], ['control ["BM9170095145"]', ['BM9170095145'], [7, False]], ['control ["US0378331005"]', ['US0378331005'], [5, True]]], [['regression ["U10378331005"]', ['U10378331005'], 'malformed'], ['regression ["1S0378331005"]', ['1S0378331005'], 'malformed'], ['control ["US0378331005"]', ['US0378331005'], [5, True]], ['control ["US5949181045"]', ['US5949181045'], [5, True]], ['control ["GB0002634946"]', ['GB0002634946'], [6, True]], ['control ["AU0000XVGZA3"]', ['AU0000XVGZA3'], [3, True]], ['control ["DE000BAY0017"]', ['DE000BAY0017'], [7, True]], ['control ["US037833100"]', ['US037833100'], 'malformed']], [['regression ["1S0378331005"]', ['1S0378331005'], 'malformed'], ['regression ["U10378331005"]', ['U10378331005'], 'malformed'], ['control ["US037833100"]', ['US037833100'], 'malformed'], ['control ["us0378331005"]', ['us0378331005'], 'malformed'], ['control ["US03783310a5"]', ['US03783310a5'], 'malformed'], ['control ["12Q037833100"]', ['12Q037833100'], 'malformed'], ['control ["XS2021832634"]', ['XS2021832634'], [4, True]], ['control ["US38259P5089"]', ['US38259P5089'], [9, True]]]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression ["1S0378331005"] | malformed | malformed | Passed |
| regression ["U10378331005"] | malformed | malformed | Passed |
| control ["US4V5PGS4IX8"] | [0, False] | [0, False] | Passed |
| control ["GBOV8F5J6090"] | [7, False] | [7, False] | Passed |
| control ["DEC85GG2TSS1"] | [4, False] | [4, False] | Passed |
| control ["JPFWKDL124I1"] | [1, True] | [1, True] | Passed |
| control ["CHXVXSVIT016"] | [1, False] | [1, False] | Passed |
| control ["FRLWNIYHPT37"] | [5, False] | [5, False] | Passed |
SHA-256 / 7b76537145d32af6397188797d940b0cbc18d9277d981a99b247ce09a3b07fb1
Verification & scope
A deterministic, bounded teaching model of the named scheme under the stated contract; not a certified validator. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:48:37.932315+00:00.
Case digest / 48151244a94227f1867412e5ee389501b7955ca9c562bf8c5ee8a6de10fd55f8