FAILURE MAP
← Case archive

FA-72511 / Check-digit algorithms / Open access

VIN writes remainder ten as the digit 0 · case 01

VINs whose check character is X are rejected.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The check is str(r % 10), so remainder 10 becomes "0" instead of "X".

VERIFIED REPAIR

Write remainder 10 as the letter X.

Unsuccessful approach: Writing remainder 10 as "10" produces a two-character check that never matches.

Case contract

North American 17-character VIN check digit. Input must be 17 uppercase ASCII alphanumerics without I, O or Q (else "malformed"). Letters transliterate (A-H 1-8, J-N 1-5, P 7, R 9, S-Z 2-9); weights are 8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2 with weight 0 on the check position (9th). Remainder mod 11 is the check digit, 10 written X. Return [check character, whether position 9 matches].

Why this case matters

Vehicle registration and recall systems reject VINs with a bad check digit.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(vin):
    TR = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7, 'H': 8, 'J': 1, 'K': 2, 'L': 3, 'M': 4, 'N': 5, 'P': 7, 'R': 9, 'S': 2, 'T': 3, 'U': 4, 'V': 5, 'W': 6, 'X': 7, 'Y': 8, 'Z': 9}
    W = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2]
    if len(vin) != 17 or not vin.isascii() or not vin.isalnum() or vin != vin.upper():
        return 'malformed'
    if any(ch in 'IOQ' for ch in vin):
        return 'malformed'
    total = 0
    for ch, w in zip(vin, W):
        total += (int(ch) if ch.isdigit() else TR[ch]) * w
    r = total % 11
    check = str(r % 10)
    return [check, vin[8] == check]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['regression ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["7P852FPZ9AMB30TWM"]', ['7P852FPZ9AMB30TWM'], ['1', False]], ['control ["NRCAB2B221G6DGFEU"]', ['NRCAB2B221G6DGFEU'], ['3', False]], ['control ["802LPLKT5RR2033BP"]', ['802LPLKT5RR2033BP'], ['2', False]], ['control ["G9Y36GVM3T01TBX5P"]', ['G9Y36GVM3T01TBX5P'], ['0', False]], ['control ["J5KCLF4060VP1YCZT"]', ['J5KCLF4060VP1YCZT'], ['2', False]], ['control ["7U176LUC2HMRHV49Y"]', ['7U176LUC2HMRHV49Y'], ['0', False]]], [['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['regression ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["7U176LUC2HMRHV49Y"]', ['7U176LUC2HMRHV49Y'], ['0', False]], ['control ["T32AS501XMK3869UE"]', ['T32AS501XMK3869UE'], ['7', False]], ['control ["9D9WJN8Z6UAEAXNMY"]', ['9D9WJN8Z6UAEAXNMY'], ['4', False]], ['control ["G746XY1N49VVXVM2N"]', ['G746XY1N49VVXVM2N'], ['1', False]], ['control ["A2C3SUET4AT9FGY0N"]', ['A2C3SUET4AT9FGY0N'], ['5', False]], ['control ["ZP4DXW7F59ZF0J6LD"]', ['ZP4DXW7F59ZF0J6LD'], ['9', False]]], [['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['regression ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["ZP4DXW7F59ZF0J6LD"]', ['ZP4DXW7F59ZF0J6LD'], ['9', False]], ['control ["XASS3C3Z3KGD2JETV"]', ['XASS3C3Z3KGD2JETV'], ['8', False]], ['control ["4E2898314S7811191"]', ['4E2898314S7811191'], ['6', False]], ['control ["952403649S86181S3"]', ['952403649S86181S3'], ['1', False]], ['control ["F32A05CF4S3S80512"]', ['F32A05CF4S3S80512'], ['1', False]], ['control ["6C2F00FD7S2507305"]', ['6C2F00FD7S2507305'], ['3', False]]], [['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['regression ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["6C2F00FD7S2507305"]', ['6C2F00FD7S2507305'], ['3', False]], ['control ["11111111111111111"]', ['11111111111111111'], ['1', True]], ['control ["1HGCM82633A004352"]', ['1HGCM82633A004352'], ['3', True]], ['control ["JH4KA7561PC008269"]', ['JH4KA7561PC008269'], ['1', True]], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed']], [['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['regression ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["5YJSA1E14HF000001"]', ['5YJSA1E14HF000001'], ['8', False]], ['control ["WVWZZZ1JZ3W386752"]', ['WVWZZZ1JZ3W386752'], ['9', False]], ['control ["SALVA2AE4EH877482"]', ['SALVA2AE4EH877482'], ['7', False]], ['control ["7P852FPZ9AMB30TWM"]', ['7P852FPZ9AMB30TWM'], ['1', False]]]]
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 fixtureActualExpectedOutcome
regression ["5E80302J20HS0C2TB"]['0', False]['X', False]Failed
regression ["466JDFJ71TZ0MJCXA"]['0', False]['X', False]Failed
control ["7P852FPZ9AMB30TWM"]['1', False]['1', False]Passed
control ["NRCAB2B221G6DGFEU"]['3', False]['3', False]Passed
control ["802LPLKT5RR2033BP"]['2', False]['2', False]Passed
control ["G9Y36GVM3T01TBX5P"]['0', False]['0', False]Passed
control ["J5KCLF4060VP1YCZT"]['2', False]['2', False]Passed
control ["7U176LUC2HMRHV49Y"]['0', False]['0', False]Passed

SHA-256 / f75ee3e4cc573d26054cc66e72505441da0459381af0edf28f3f810c861e31f9

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(vin):
    TR = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7, 'H': 8, 'J': 1, 'K': 2, 'L': 3, 'M': 4, 'N': 5, 'P': 7, 'R': 9, 'S': 2, 'T': 3, 'U': 4, 'V': 5, 'W': 6, 'X': 7, 'Y': 8, 'Z': 9}
    W = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2]
    if len(vin) != 17 or not vin.isascii() or not vin.isalnum() or vin != vin.upper():
        return 'malformed'
    if any(ch in 'IOQ' for ch in vin):
        return 'malformed'
    total = 0
    for ch, w in zip(vin, W):
        total += (int(ch) if ch.isdigit() else TR[ch]) * w
    r = total % 11
    check = str(r)
    return [check, vin[8] == check]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['regression ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["7P852FPZ9AMB30TWM"]', ['7P852FPZ9AMB30TWM'], ['1', False]], ['control ["NRCAB2B221G6DGFEU"]', ['NRCAB2B221G6DGFEU'], ['3', False]], ['control ["802LPLKT5RR2033BP"]', ['802LPLKT5RR2033BP'], ['2', False]], ['control ["G9Y36GVM3T01TBX5P"]', ['G9Y36GVM3T01TBX5P'], ['0', False]], ['control ["J5KCLF4060VP1YCZT"]', ['J5KCLF4060VP1YCZT'], ['2', False]], ['control ["7U176LUC2HMRHV49Y"]', ['7U176LUC2HMRHV49Y'], ['0', False]]], [['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['regression ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["7U176LUC2HMRHV49Y"]', ['7U176LUC2HMRHV49Y'], ['0', False]], ['control ["T32AS501XMK3869UE"]', ['T32AS501XMK3869UE'], ['7', False]], ['control ["9D9WJN8Z6UAEAXNMY"]', ['9D9WJN8Z6UAEAXNMY'], ['4', False]], ['control ["G746XY1N49VVXVM2N"]', ['G746XY1N49VVXVM2N'], ['1', False]], ['control ["A2C3SUET4AT9FGY0N"]', ['A2C3SUET4AT9FGY0N'], ['5', False]], ['control ["ZP4DXW7F59ZF0J6LD"]', ['ZP4DXW7F59ZF0J6LD'], ['9', False]]], [['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['regression ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["ZP4DXW7F59ZF0J6LD"]', ['ZP4DXW7F59ZF0J6LD'], ['9', False]], ['control ["XASS3C3Z3KGD2JETV"]', ['XASS3C3Z3KGD2JETV'], ['8', False]], ['control ["4E2898314S7811191"]', ['4E2898314S7811191'], ['6', False]], ['control ["952403649S86181S3"]', ['952403649S86181S3'], ['1', False]], ['control ["F32A05CF4S3S80512"]', ['F32A05CF4S3S80512'], ['1', False]], ['control ["6C2F00FD7S2507305"]', ['6C2F00FD7S2507305'], ['3', False]]], [['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['regression ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["6C2F00FD7S2507305"]', ['6C2F00FD7S2507305'], ['3', False]], ['control ["11111111111111111"]', ['11111111111111111'], ['1', True]], ['control ["1HGCM82633A004352"]', ['1HGCM82633A004352'], ['3', True]], ['control ["JH4KA7561PC008269"]', ['JH4KA7561PC008269'], ['1', True]], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed']], [['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['regression ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["5YJSA1E14HF000001"]', ['5YJSA1E14HF000001'], ['8', False]], ['control ["WVWZZZ1JZ3W386752"]', ['WVWZZZ1JZ3W386752'], ['9', False]], ['control ["SALVA2AE4EH877482"]', ['SALVA2AE4EH877482'], ['7', False]], ['control ["7P852FPZ9AMB30TWM"]', ['7P852FPZ9AMB30TWM'], ['1', False]]]]
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 fixtureActualExpectedOutcome
regression ["5E80302J20HS0C2TB"]['10', False]['X', False]Failed
regression ["466JDFJ71TZ0MJCXA"]['10', False]['X', False]Failed
control ["7P852FPZ9AMB30TWM"]['1', False]['1', False]Passed
control ["NRCAB2B221G6DGFEU"]['3', False]['3', False]Passed
control ["802LPLKT5RR2033BP"]['2', False]['2', False]Passed
control ["G9Y36GVM3T01TBX5P"]['0', False]['0', False]Passed
control ["J5KCLF4060VP1YCZT"]['2', False]['2', False]Passed
control ["7U176LUC2HMRHV49Y"]['0', False]['0', False]Passed

SHA-256 / b3d757982badd690eb1bc46fa9994d78a661b77c2428c411096edcfdcf3bef3c

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(vin):
    TR = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7, 'H': 8, 'J': 1, 'K': 2, 'L': 3, 'M': 4, 'N': 5, 'P': 7, 'R': 9, 'S': 2, 'T': 3, 'U': 4, 'V': 5, 'W': 6, 'X': 7, 'Y': 8, 'Z': 9}
    W = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2]
    if len(vin) != 17 or not vin.isascii() or not vin.isalnum() or vin != vin.upper():
        return 'malformed'
    if any(ch in 'IOQ' for ch in vin):
        return 'malformed'
    total = 0
    for ch, w in zip(vin, W):
        total += (int(ch) if ch.isdigit() else TR[ch]) * w
    r = total % 11
    check = 'X' if r == 10 else str(r)
    return [check, vin[8] == check]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['regression ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["7P852FPZ9AMB30TWM"]', ['7P852FPZ9AMB30TWM'], ['1', False]], ['control ["NRCAB2B221G6DGFEU"]', ['NRCAB2B221G6DGFEU'], ['3', False]], ['control ["802LPLKT5RR2033BP"]', ['802LPLKT5RR2033BP'], ['2', False]], ['control ["G9Y36GVM3T01TBX5P"]', ['G9Y36GVM3T01TBX5P'], ['0', False]], ['control ["J5KCLF4060VP1YCZT"]', ['J5KCLF4060VP1YCZT'], ['2', False]], ['control ["7U176LUC2HMRHV49Y"]', ['7U176LUC2HMRHV49Y'], ['0', False]]], [['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['regression ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["7U176LUC2HMRHV49Y"]', ['7U176LUC2HMRHV49Y'], ['0', False]], ['control ["T32AS501XMK3869UE"]', ['T32AS501XMK3869UE'], ['7', False]], ['control ["9D9WJN8Z6UAEAXNMY"]', ['9D9WJN8Z6UAEAXNMY'], ['4', False]], ['control ["G746XY1N49VVXVM2N"]', ['G746XY1N49VVXVM2N'], ['1', False]], ['control ["A2C3SUET4AT9FGY0N"]', ['A2C3SUET4AT9FGY0N'], ['5', False]], ['control ["ZP4DXW7F59ZF0J6LD"]', ['ZP4DXW7F59ZF0J6LD'], ['9', False]]], [['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['regression ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["ZP4DXW7F59ZF0J6LD"]', ['ZP4DXW7F59ZF0J6LD'], ['9', False]], ['control ["XASS3C3Z3KGD2JETV"]', ['XASS3C3Z3KGD2JETV'], ['8', False]], ['control ["4E2898314S7811191"]', ['4E2898314S7811191'], ['6', False]], ['control ["952403649S86181S3"]', ['952403649S86181S3'], ['1', False]], ['control ["F32A05CF4S3S80512"]', ['F32A05CF4S3S80512'], ['1', False]], ['control ["6C2F00FD7S2507305"]', ['6C2F00FD7S2507305'], ['3', False]]], [['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['regression ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["6C2F00FD7S2507305"]', ['6C2F00FD7S2507305'], ['3', False]], ['control ["11111111111111111"]', ['11111111111111111'], ['1', True]], ['control ["1HGCM82633A004352"]', ['1HGCM82633A004352'], ['3', True]], ['control ["JH4KA7561PC008269"]', ['JH4KA7561PC008269'], ['1', True]], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed']], [['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['regression ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["5YJSA1E14HF000001"]', ['5YJSA1E14HF000001'], ['8', False]], ['control ["WVWZZZ1JZ3W386752"]', ['WVWZZZ1JZ3W386752'], ['9', False]], ['control ["SALVA2AE4EH877482"]', ['SALVA2AE4EH877482'], ['7', False]], ['control ["7P852FPZ9AMB30TWM"]', ['7P852FPZ9AMB30TWM'], ['1', False]]]]
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 fixtureActualExpectedOutcome
regression ["5E80302J20HS0C2TB"]['X', False]['X', False]Passed
regression ["466JDFJ71TZ0MJCXA"]['X', False]['X', False]Passed
control ["7P852FPZ9AMB30TWM"]['1', False]['1', False]Passed
control ["NRCAB2B221G6DGFEU"]['3', False]['3', False]Passed
control ["802LPLKT5RR2033BP"]['2', False]['2', False]Passed
control ["G9Y36GVM3T01TBX5P"]['0', False]['0', False]Passed
control ["J5KCLF4060VP1YCZT"]['2', False]['2', False]Passed
control ["7U176LUC2HMRHV49Y"]['0', False]['0', False]Passed

SHA-256 / 88ad0a2704dde8145e9e16bb2d49daa64de43f00c8761297155da72369684935

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:39.160728+00:00.

Case digest / 469d17cd903764505cd104e1a75c26110abfc6f02b1d9fcdc0900712a4e310ae