FAILURE MAP
← Case archive

FA-72451 / Check-digit algorithms / Open access

GTIN weights are aligned from the left · case 01

GTIN-13 numbers fail while GTIN-8, -12 and -14 still validate.

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

ROOT CAUSE

The weights are assigned from the leftmost digit, which only coincides with right alignment for odd body lengths.

VERIFIED REPAIR

Assign weight 3 to the body digit adjacent to the check digit and alternate leftwards.

Unsuccessful approach: Flipping the left-aligned weights to start with 1 repairs GTIN-13 but breaks the other lengths.

Case contract

Validate a GTIN-8, GTIN-12, GTIN-13 or GTIN-14 given as ASCII digits (any other length or character: "malformed"). Weights 3,1 alternate starting with 3 on the digit immediately left of the check digit, so the alignment is from the right for every length. Return [kind, check digit matches].

Why this case matters

Retail and logistics scanners accept several GTIN lengths through one validator.

1 / The failure

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

N = 1
observations = []
def solve(s):
    if not s.isascii() or not s.isdigit() or len(s) not in (8, 12, 13, 14):
        return 'malformed'
    body = s[:-1]
    total = 0
    for i, ch in enumerate(body):
        total += int(ch) * (3 if i % 2 == 0 else 1)
    check = (10 - total % 10) % 10
    kind = {8: 'GTIN-8', 12: 'GTIN-12', 13: 'GTIN-13', 14: 'GTIN-14'}[len(s)]
    return [kind, check == int(s[-1])]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression ["0916391037047"]', ['0916391037047'], ['GTIN-13', True]], ['regression ["8847703723452"]', ['8847703723452'], ['GTIN-13', True]], ['partial-repair ["07251955"]', ['07251955'], ['GTIN-8', True]], ['partial-repair ["934235100467"]', ['934235100467'], ['GTIN-12', True]], ['control ["07251952"]', ['07251952'], ['GTIN-8', False]], ['control ["934235100464"]', ['934235100464'], ['GTIN-12', False]], ['control ["0916391037044"]', ['0916391037044'], ['GTIN-13', False]], ['control ["59804222888445"]', ['59804222888445'], ['GTIN-14', False]]], [['regression ["4006381333931"]', ['4006381333931'], ['GTIN-13', True]], ['regression ["0916391037047"]', ['0916391037047'], ['GTIN-13', True]], ['partial-repair ["033345301891"]', ['033345301891'], ['GTIN-12', True]], ['partial-repair ["12641161"]', ['12641161'], ['GTIN-8', True]], ['control ["033345301898"]', ['033345301898'], ['GTIN-12', False]], ['control ["12641168"]', ['12641168'], ['GTIN-8', False]], ['control ["84650644669478"]', ['84650644669478'], ['GTIN-14', False]], ['control ["6916522076168"]', ['6916522076168'], ['GTIN-13', False]]], [['regression ["6916522076161"]', ['6916522076161'], ['GTIN-13', True]], ['regression ["4006381333931"]', ['4006381333931'], ['GTIN-13', True]], ['partial-repair ["036000291452"]', ['036000291452'], ['GTIN-12', True]], ['partial-repair ["10614141000415"]', ['10614141000415'], ['GTIN-14', True]], ['control ["4006381333932"]', ['4006381333932'], ['GTIN-13', False]], ['control ["0"]', ['0'], 'malformed'], ['control ["123456789012345"]', ['123456789012345'], 'malformed'], ['control ["400638133393"]', ['400638133393'], ['GTIN-12', False]]], [['regression ["8847703723452"]', ['8847703723452'], ['GTIN-13', True]], ['regression ["6916522076161"]', ['6916522076161'], ['GTIN-13', True]], ['partial-repair ["934235100467"]', ['934235100467'], ['GTIN-12', True]], ['partial-repair ["59804222888448"]', ['59804222888448'], ['GTIN-14', True]], ['control ["00000000"]', ['00000000'], ['GTIN-8', True]], ['control ["9780306406157"]', ['9780306406157'], ['GTIN-13', True]], ['control ["5901234123457"]', ['5901234123457'], ['GTIN-13', True]], ['control ["07251952"]', ['07251952'], ['GTIN-8', False]]], [['regression ["0916391037047"]', ['0916391037047'], ['GTIN-13', True]], ['regression ["8847703723452"]', ['8847703723452'], ['GTIN-13', True]], ['partial-repair ["12641161"]', ['12641161'], ['GTIN-8', True]], ['partial-repair ["84650644669471"]', ['84650644669471'], ['GTIN-14', True]], ['control ["0916391037044"]', ['0916391037044'], ['GTIN-13', False]], ['control ["59804222888445"]', ['59804222888445'], ['GTIN-14', False]], ['control ["8847703723459"]', ['8847703723459'], ['GTIN-13', False]], ['control ["033345301898"]', ['033345301898'], ['GTIN-12', 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 ["0916391037047"]['GTIN-13', False]['GTIN-13', True]Failed
regression ["8847703723452"]['GTIN-13', False]['GTIN-13', True]Failed
partial-repair ["07251955"]['GTIN-8', True]['GTIN-8', True]Passed
partial-repair ["934235100467"]['GTIN-12', True]['GTIN-12', True]Passed
control ["07251952"]['GTIN-8', False]['GTIN-8', False]Passed
control ["934235100464"]['GTIN-12', False]['GTIN-12', False]Passed
control ["0916391037044"]['GTIN-13', False]['GTIN-13', False]Passed
control ["59804222888445"]['GTIN-14', False]['GTIN-14', False]Passed

SHA-256 / 685c3c102811ea7854939ac709e04fd5eed003917b83adcac15822056042c3ba

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(s):
    if not s.isascii() or not s.isdigit() or len(s) not in (8, 12, 13, 14):
        return 'malformed'
    body = s[:-1]
    total = 0
    for i, ch in enumerate(body):
        total += int(ch) * (1 if i % 2 == 0 else 3)
    check = (10 - total % 10) % 10
    kind = {8: 'GTIN-8', 12: 'GTIN-12', 13: 'GTIN-13', 14: 'GTIN-14'}[len(s)]
    return [kind, check == int(s[-1])]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression ["0916391037047"]', ['0916391037047'], ['GTIN-13', True]], ['regression ["8847703723452"]', ['8847703723452'], ['GTIN-13', True]], ['partial-repair ["07251955"]', ['07251955'], ['GTIN-8', True]], ['partial-repair ["934235100467"]', ['934235100467'], ['GTIN-12', True]], ['control ["07251952"]', ['07251952'], ['GTIN-8', False]], ['control ["934235100464"]', ['934235100464'], ['GTIN-12', False]], ['control ["0916391037044"]', ['0916391037044'], ['GTIN-13', False]], ['control ["59804222888445"]', ['59804222888445'], ['GTIN-14', False]]], [['regression ["4006381333931"]', ['4006381333931'], ['GTIN-13', True]], ['regression ["0916391037047"]', ['0916391037047'], ['GTIN-13', True]], ['partial-repair ["033345301891"]', ['033345301891'], ['GTIN-12', True]], ['partial-repair ["12641161"]', ['12641161'], ['GTIN-8', True]], ['control ["033345301898"]', ['033345301898'], ['GTIN-12', False]], ['control ["12641168"]', ['12641168'], ['GTIN-8', False]], ['control ["84650644669478"]', ['84650644669478'], ['GTIN-14', False]], ['control ["6916522076168"]', ['6916522076168'], ['GTIN-13', False]]], [['regression ["6916522076161"]', ['6916522076161'], ['GTIN-13', True]], ['regression ["4006381333931"]', ['4006381333931'], ['GTIN-13', True]], ['partial-repair ["036000291452"]', ['036000291452'], ['GTIN-12', True]], ['partial-repair ["10614141000415"]', ['10614141000415'], ['GTIN-14', True]], ['control ["4006381333932"]', ['4006381333932'], ['GTIN-13', False]], ['control ["0"]', ['0'], 'malformed'], ['control ["123456789012345"]', ['123456789012345'], 'malformed'], ['control ["400638133393"]', ['400638133393'], ['GTIN-12', False]]], [['regression ["8847703723452"]', ['8847703723452'], ['GTIN-13', True]], ['regression ["6916522076161"]', ['6916522076161'], ['GTIN-13', True]], ['partial-repair ["934235100467"]', ['934235100467'], ['GTIN-12', True]], ['partial-repair ["59804222888448"]', ['59804222888448'], ['GTIN-14', True]], ['control ["00000000"]', ['00000000'], ['GTIN-8', True]], ['control ["9780306406157"]', ['9780306406157'], ['GTIN-13', True]], ['control ["5901234123457"]', ['5901234123457'], ['GTIN-13', True]], ['control ["07251952"]', ['07251952'], ['GTIN-8', False]]], [['regression ["0916391037047"]', ['0916391037047'], ['GTIN-13', True]], ['regression ["8847703723452"]', ['8847703723452'], ['GTIN-13', True]], ['partial-repair ["12641161"]', ['12641161'], ['GTIN-8', True]], ['partial-repair ["84650644669471"]', ['84650644669471'], ['GTIN-14', True]], ['control ["0916391037044"]', ['0916391037044'], ['GTIN-13', False]], ['control ["59804222888445"]', ['59804222888445'], ['GTIN-14', False]], ['control ["8847703723459"]', ['8847703723459'], ['GTIN-13', False]], ['control ["033345301898"]', ['033345301898'], ['GTIN-12', 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 ["0916391037047"]['GTIN-13', True]['GTIN-13', True]Passed
regression ["8847703723452"]['GTIN-13', True]['GTIN-13', True]Passed
partial-repair ["07251955"]['GTIN-8', False]['GTIN-8', True]Failed
partial-repair ["934235100467"]['GTIN-12', False]['GTIN-12', True]Failed
control ["07251952"]['GTIN-8', False]['GTIN-8', False]Passed
control ["934235100464"]['GTIN-12', False]['GTIN-12', False]Passed
control ["0916391037044"]['GTIN-13', False]['GTIN-13', False]Passed
control ["59804222888445"]['GTIN-14', False]['GTIN-14', False]Passed

SHA-256 / 4efee79ba01b95d774c802f2feadc9a277aa45e643315a8528e4f64770cc8158

3 / The verified repair

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

N = 1
observations = []
def solve(s):
    if not s.isascii() or not s.isdigit() or len(s) not in (8, 12, 13, 14):
        return 'malformed'
    body = s[:-1]
    total = 0
    for i, ch in enumerate(reversed(body)):
        total += int(ch) * (3 if i % 2 == 0 else 1)
    check = (10 - total % 10) % 10
    kind = {8: 'GTIN-8', 12: 'GTIN-12', 13: 'GTIN-13', 14: 'GTIN-14'}[len(s)]
    return [kind, check == int(s[-1])]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression ["0916391037047"]', ['0916391037047'], ['GTIN-13', True]], ['regression ["8847703723452"]', ['8847703723452'], ['GTIN-13', True]], ['partial-repair ["07251955"]', ['07251955'], ['GTIN-8', True]], ['partial-repair ["934235100467"]', ['934235100467'], ['GTIN-12', True]], ['control ["07251952"]', ['07251952'], ['GTIN-8', False]], ['control ["934235100464"]', ['934235100464'], ['GTIN-12', False]], ['control ["0916391037044"]', ['0916391037044'], ['GTIN-13', False]], ['control ["59804222888445"]', ['59804222888445'], ['GTIN-14', False]]], [['regression ["4006381333931"]', ['4006381333931'], ['GTIN-13', True]], ['regression ["0916391037047"]', ['0916391037047'], ['GTIN-13', True]], ['partial-repair ["033345301891"]', ['033345301891'], ['GTIN-12', True]], ['partial-repair ["12641161"]', ['12641161'], ['GTIN-8', True]], ['control ["033345301898"]', ['033345301898'], ['GTIN-12', False]], ['control ["12641168"]', ['12641168'], ['GTIN-8', False]], ['control ["84650644669478"]', ['84650644669478'], ['GTIN-14', False]], ['control ["6916522076168"]', ['6916522076168'], ['GTIN-13', False]]], [['regression ["6916522076161"]', ['6916522076161'], ['GTIN-13', True]], ['regression ["4006381333931"]', ['4006381333931'], ['GTIN-13', True]], ['partial-repair ["036000291452"]', ['036000291452'], ['GTIN-12', True]], ['partial-repair ["10614141000415"]', ['10614141000415'], ['GTIN-14', True]], ['control ["4006381333932"]', ['4006381333932'], ['GTIN-13', False]], ['control ["0"]', ['0'], 'malformed'], ['control ["123456789012345"]', ['123456789012345'], 'malformed'], ['control ["400638133393"]', ['400638133393'], ['GTIN-12', False]]], [['regression ["8847703723452"]', ['8847703723452'], ['GTIN-13', True]], ['regression ["6916522076161"]', ['6916522076161'], ['GTIN-13', True]], ['partial-repair ["934235100467"]', ['934235100467'], ['GTIN-12', True]], ['partial-repair ["59804222888448"]', ['59804222888448'], ['GTIN-14', True]], ['control ["00000000"]', ['00000000'], ['GTIN-8', True]], ['control ["9780306406157"]', ['9780306406157'], ['GTIN-13', True]], ['control ["5901234123457"]', ['5901234123457'], ['GTIN-13', True]], ['control ["07251952"]', ['07251952'], ['GTIN-8', False]]], [['regression ["0916391037047"]', ['0916391037047'], ['GTIN-13', True]], ['regression ["8847703723452"]', ['8847703723452'], ['GTIN-13', True]], ['partial-repair ["12641161"]', ['12641161'], ['GTIN-8', True]], ['partial-repair ["84650644669471"]', ['84650644669471'], ['GTIN-14', True]], ['control ["0916391037044"]', ['0916391037044'], ['GTIN-13', False]], ['control ["59804222888445"]', ['59804222888445'], ['GTIN-14', False]], ['control ["8847703723459"]', ['8847703723459'], ['GTIN-13', False]], ['control ["033345301898"]', ['033345301898'], ['GTIN-12', 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 ["0916391037047"]['GTIN-13', True]['GTIN-13', True]Passed
regression ["8847703723452"]['GTIN-13', True]['GTIN-13', True]Passed
partial-repair ["07251955"]['GTIN-8', True]['GTIN-8', True]Passed
partial-repair ["934235100467"]['GTIN-12', True]['GTIN-12', True]Passed
control ["07251952"]['GTIN-8', False]['GTIN-8', False]Passed
control ["934235100464"]['GTIN-12', False]['GTIN-12', False]Passed
control ["0916391037044"]['GTIN-13', False]['GTIN-13', False]Passed
control ["59804222888445"]['GTIN-14', False]['GTIN-14', False]Passed

SHA-256 / 3cb41234dd399b46c318b12d7564151c99d7360752f9962599a089adead2ed75

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

Case digest / 116d7e82aee8ff22c61486c1d187023a4e50178fa5681ad12d4d50ff66d89659