FA-72506 / Check-digit algorithms / Open access
VIN weights drop the zero weight at the check position · case 01
Almost every VIN gets a wrong check digit.
ROOT CAUSE
The weight list omits the 0 for position 9, so every later weight shifts one position left.
VERIFIED REPAIR
Keep 17 weights with 0 at the check digit position.
Unsuccessful approach: Restoring 17 weights but with 1 at the check position makes the check digit contribute to its own sum.
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, 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 ["7P852FPZ9AMB30TWM"]', ['7P852FPZ9AMB30TWM'], ['1', False]], ['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["802LPLKT5RR2033BP"]', ['802LPLKT5RR2033BP'], ['2', False]], ['control ["G9Y36GVM3T01TBX5P"]', ['G9Y36GVM3T01TBX5P'], ['0', False]], ['control ["J5KCLF4060VP1YCZT"]', ['J5KCLF4060VP1YCZT'], ['2', False]]], [['regression ["802LPLKT5RR2033BP"]', ['802LPLKT5RR2033BP'], ['2', False]], ['regression ["G9Y36GVM3T01TBX5P"]', ['G9Y36GVM3T01TBX5P'], ['0', False]], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["9D9WJN8Z6UAEAXNMY"]', ['9D9WJN8Z6UAEAXNMY'], ['4', False]], ['control ["G746XY1N49VVXVM2N"]', ['G746XY1N49VVXVM2N'], ['1', False]], ['control ["A2C3SUET4AT9FGY0N"]', ['A2C3SUET4AT9FGY0N'], ['5', False]]], [['regression ["7U176LUC2HMRHV49Y"]', ['7U176LUC2HMRHV49Y'], ['0', False]], ['regression ["T32AS501XMK3869UE"]', ['T32AS501XMK3869UE'], ['7', False]], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["4E2898314S7811191"]', ['4E2898314S7811191'], ['6', False]], ['control ["952403649S86181S3"]', ['952403649S86181S3'], ['1', False]]], [['regression ["ZP4DXW7F59ZF0J6LD"]', ['ZP4DXW7F59ZF0J6LD'], ['9', False]], ['regression ["XASS3C3Z3KGD2JETV"]', ['XASS3C3Z3KGD2JETV'], ['8', False]], ['partial-repair ["G746XY1N49VVXVM2N"]', ['G746XY1N49VVXVM2N'], ['1', False]], ['partial-repair ["A2C3SUET4AT9FGY0N"]', ['A2C3SUET4AT9FGY0N'], ['5', False]], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["1M8GDM9AXKP042788"]', ['1M8GDM9AXKP042788'], ['X', True]]], [['regression ["4E2898314S7811191"]', ['4E2898314S7811191'], ['6', False]], ['regression ["952403649S86181S3"]', ['952403649S86181S3'], ['1', False]], ['partial-repair ["XASS3C3Z3KGD2JETV"]', ['XASS3C3Z3KGD2JETV'], ['8', False]], ['partial-repair ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["5YJSA1E14HF000001"]', ['5YJSA1E14HF000001'], ['8', 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression ["7P852FPZ9AMB30TWM"] | ['0', False] | ['1', False] | Failed |
| regression ["5E80302J20HS0C2TB"] | ['6', False] | ['X', False] | Failed |
| control ["1M8GDM9AXKP04278"] | malformed | malformed | Passed |
| control ["1M8GDM9AXKP04278O"] | malformed | malformed | Passed |
| control ["1m8gdm9axkp042788"] | malformed | malformed | Passed |
| control ["802LPLKT5RR2033BP"] | ['5', True] | ['2', False] | Failed |
| control ["G9Y36GVM3T01TBX5P"] | ['3', True] | ['0', False] | Failed |
| control ["J5KCLF4060VP1YCZT"] | ['6', True] | ['2', False] | Failed |
SHA-256 / 41cd9f594b0c108bbbc81f587e16cd6f5b03ff48695b1664df8539fa710fb2bf
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, 1, 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 ["7P852FPZ9AMB30TWM"]', ['7P852FPZ9AMB30TWM'], ['1', False]], ['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["802LPLKT5RR2033BP"]', ['802LPLKT5RR2033BP'], ['2', False]], ['control ["G9Y36GVM3T01TBX5P"]', ['G9Y36GVM3T01TBX5P'], ['0', False]], ['control ["J5KCLF4060VP1YCZT"]', ['J5KCLF4060VP1YCZT'], ['2', False]]], [['regression ["802LPLKT5RR2033BP"]', ['802LPLKT5RR2033BP'], ['2', False]], ['regression ["G9Y36GVM3T01TBX5P"]', ['G9Y36GVM3T01TBX5P'], ['0', False]], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["9D9WJN8Z6UAEAXNMY"]', ['9D9WJN8Z6UAEAXNMY'], ['4', False]], ['control ["G746XY1N49VVXVM2N"]', ['G746XY1N49VVXVM2N'], ['1', False]], ['control ["A2C3SUET4AT9FGY0N"]', ['A2C3SUET4AT9FGY0N'], ['5', False]]], [['regression ["7U176LUC2HMRHV49Y"]', ['7U176LUC2HMRHV49Y'], ['0', False]], ['regression ["T32AS501XMK3869UE"]', ['T32AS501XMK3869UE'], ['7', False]], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["4E2898314S7811191"]', ['4E2898314S7811191'], ['6', False]], ['control ["952403649S86181S3"]', ['952403649S86181S3'], ['1', False]]], [['regression ["ZP4DXW7F59ZF0J6LD"]', ['ZP4DXW7F59ZF0J6LD'], ['9', False]], ['regression ["XASS3C3Z3KGD2JETV"]', ['XASS3C3Z3KGD2JETV'], ['8', False]], ['partial-repair ["G746XY1N49VVXVM2N"]', ['G746XY1N49VVXVM2N'], ['1', False]], ['partial-repair ["A2C3SUET4AT9FGY0N"]', ['A2C3SUET4AT9FGY0N'], ['5', False]], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["1M8GDM9AXKP042788"]', ['1M8GDM9AXKP042788'], ['X', True]]], [['regression ["4E2898314S7811191"]', ['4E2898314S7811191'], ['6', False]], ['regression ["952403649S86181S3"]', ['952403649S86181S3'], ['1', False]], ['partial-repair ["XASS3C3Z3KGD2JETV"]', ['XASS3C3Z3KGD2JETV'], ['8', False]], ['partial-repair ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["5YJSA1E14HF000001"]', ['5YJSA1E14HF000001'], ['8', 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression ["7P852FPZ9AMB30TWM"] | ['X', False] | ['1', False] | Failed |
| regression ["5E80302J20HS0C2TB"] | ['1', False] | ['X', False] | Failed |
| control ["1M8GDM9AXKP04278"] | malformed | malformed | Passed |
| control ["1M8GDM9AXKP04278O"] | malformed | malformed | Passed |
| control ["1m8gdm9axkp042788"] | malformed | malformed | Passed |
| control ["802LPLKT5RR2033BP"] | ['7', False] | ['2', False] | Failed |
| control ["G9Y36GVM3T01TBX5P"] | ['3', True] | ['0', False] | Failed |
| control ["J5KCLF4060VP1YCZT"] | ['8', False] | ['2', False] | Failed |
SHA-256 / d9b2febaef401ef36588f2a66a2e3e9e6c0e0fc893ef8060e551379f95514249
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 ["7P852FPZ9AMB30TWM"]', ['7P852FPZ9AMB30TWM'], ['1', False]], ['regression ["5E80302J20HS0C2TB"]', ['5E80302J20HS0C2TB'], ['X', False]], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["802LPLKT5RR2033BP"]', ['802LPLKT5RR2033BP'], ['2', False]], ['control ["G9Y36GVM3T01TBX5P"]', ['G9Y36GVM3T01TBX5P'], ['0', False]], ['control ["J5KCLF4060VP1YCZT"]', ['J5KCLF4060VP1YCZT'], ['2', False]]], [['regression ["802LPLKT5RR2033BP"]', ['802LPLKT5RR2033BP'], ['2', False]], ['regression ["G9Y36GVM3T01TBX5P"]', ['G9Y36GVM3T01TBX5P'], ['0', False]], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["9D9WJN8Z6UAEAXNMY"]', ['9D9WJN8Z6UAEAXNMY'], ['4', False]], ['control ["G746XY1N49VVXVM2N"]', ['G746XY1N49VVXVM2N'], ['1', False]], ['control ["A2C3SUET4AT9FGY0N"]', ['A2C3SUET4AT9FGY0N'], ['5', False]]], [['regression ["7U176LUC2HMRHV49Y"]', ['7U176LUC2HMRHV49Y'], ['0', False]], ['regression ["T32AS501XMK3869UE"]', ['T32AS501XMK3869UE'], ['7', False]], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["4E2898314S7811191"]', ['4E2898314S7811191'], ['6', False]], ['control ["952403649S86181S3"]', ['952403649S86181S3'], ['1', False]]], [['regression ["ZP4DXW7F59ZF0J6LD"]', ['ZP4DXW7F59ZF0J6LD'], ['9', False]], ['regression ["XASS3C3Z3KGD2JETV"]', ['XASS3C3Z3KGD2JETV'], ['8', False]], ['partial-repair ["G746XY1N49VVXVM2N"]', ['G746XY1N49VVXVM2N'], ['1', False]], ['partial-repair ["A2C3SUET4AT9FGY0N"]', ['A2C3SUET4AT9FGY0N'], ['5', False]], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["1M8GDM9AXKP042788"]', ['1M8GDM9AXKP042788'], ['X', True]]], [['regression ["4E2898314S7811191"]', ['4E2898314S7811191'], ['6', False]], ['regression ["952403649S86181S3"]', ['952403649S86181S3'], ['1', False]], ['partial-repair ["XASS3C3Z3KGD2JETV"]', ['XASS3C3Z3KGD2JETV'], ['8', False]], ['partial-repair ["466JDFJ71TZ0MJCXA"]', ['466JDFJ71TZ0MJCXA'], ['X', False]], ['control ["1m8gdm9axkp042788"]', ['1m8gdm9axkp042788'], 'malformed'], ['control ["1M8GDM9AXKP04278"]', ['1M8GDM9AXKP04278'], 'malformed'], ['control ["1M8GDM9AXKP04278O"]', ['1M8GDM9AXKP04278O'], 'malformed'], ['control ["5YJSA1E14HF000001"]', ['5YJSA1E14HF000001'], ['8', 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression ["7P852FPZ9AMB30TWM"] | ['1', False] | ['1', False] | Passed |
| regression ["5E80302J20HS0C2TB"] | ['X', False] | ['X', False] | Passed |
| control ["1M8GDM9AXKP04278"] | malformed | malformed | Passed |
| control ["1M8GDM9AXKP04278O"] | malformed | malformed | Passed |
| control ["1m8gdm9axkp042788"] | malformed | malformed | Passed |
| control ["802LPLKT5RR2033BP"] | ['2', False] | ['2', False] | Passed |
| control ["G9Y36GVM3T01TBX5P"] | ['0', False] | ['0', False] | Passed |
| control ["J5KCLF4060VP1YCZT"] | ['2', False] | ['2', False] | Passed |
SHA-256 / e97e2d62e9550addeeb4388686001b24144b674fe4b1c83c6a8daee223c86dbf
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.121603+00:00.
Case digest / fac6b552c577aabdde16fbf0b17c391cf045a5defad82407ad688c24d3c82707