FA-79721 / Barcode symbology encoding / Open access
EAN-2 parity is chosen from the digit sum · case 01
Magazine issue numbers decode as different issues.
ROOT CAUSE
The parity index uses the sum of the digits instead of the two-digit value.
VERIFIED REPAIR
Use the two-digit value modulo 4.
Unsuccessful approach: Using only the last digit ignores the tens digit, which changes the value modulo 4.
Case contract
Encode a two-digit EAN-2 add-on (issue number) as modules: start 1011, first character, separator 01, second character. The parity pattern is chosen by the two-digit value modulo 4: 0 LL, 1 LG, 2 GL, 3 GG, using the EAN L and G code sets. Invalid input returns None.
Why this case matters
Retail, logistics, pharmacy and document workflows depend on encoders that produce exactly the module pattern, code-set switches, separators and quiet zones scanners expect; one misplaced module or separator makes a label unreadable or, worse, scan as different data.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(s):
if len(s) != 2 or not all(c in '0123456789' for c in s):
return None
L = ['0001101', '0011001', '0010011', '0111101', '0100011', '0110001', '0101111', '0111011', '0110111', '0001011']
G = ['0100111', '0110011', '0011011', '0100001', '0011101', '0111001', '0000101', '0010001', '0001001', '0010111']
par = ['LL', 'LG', 'GL', 'GG'][(int(s[0]) + int(s[1])) % 4]
a = (L if par[0] == 'L' else G)[int(s[0])]
b = (L if par[1] == 'L' else G)[int(s[1])]
return '1011' + a + '01' + b
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['73', '10110111011010100001'], ['30', '10110100001010001101'], ['42', '10110011101010010011'], ['05', '10110001101010111001'], ['08', '10110001101010110111'], ['06', '10110100111010101111'], ['49', '10110100011010010111'], ['55', '10110111001010111001']], [['19', '10110110011010010111'], ['98', '10110010111010110111'], ['96', '10110001011010101111'], ['44', '10110100011010100011'], ['47', '10110011101010010001'], ['08', '10110001101010110111'], ['06', '10110100111010101111'], ['22', '10110011011010010011']], [['38', '10110100001010110111'], ['73', '10110111011010100001'], ['88', '10110110111010110111'], ['87', '10110001001010010001'], ['83', '10110001001010100001'], ['02', '10110100111010010011'], ['85', '10110110111010111001'], ['17', '10110011001010010001']], [['66', '10110000101010101111'], ['77', '10110111011010010001'], ['92', '10110001011010010011'], ['40', '10110100011010001101'], ['84', '10110110111010100011'], ['49', '10110100011010010111'], ['89', '10110110111010010111'], ['13', '10110011001010100001']], [['52', '10110110001010010011'], ['50', '10110111001010001101'], ['16', '10110011001010101111'], ['85', '10110110111010111001'], ['43', '10110011101010100001'], ['89', '10110110111010010111'], ['48', '10110100011010110111'], ['29', '10110010011010010111']]]
labels = ["regression: parity selector value", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("%s %d" % (labels[i % len(labels)], i), 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: parity selector value 0 | 10110010001010111101 | 10110111011010100001 | Failed |
| repair trap 1 | 10110100001010100111 | 10110100001010001101 | Failed |
| combined fault 2 | 10110011101010010011 | 10110011101010010011 | Passed |
| control 3 | 10110001101010111001 | 10110001101010111001 | Passed |
| control 4 | 10110001101010110111 | 10110001101010110111 | Passed |
| boundary 5 | 10110100111010101111 | 10110100111010101111 | Passed |
| boundary 6 | 10110100011010010111 | 10110100011010010111 | Passed |
| control 7 | 10110111001010110001 | 10110111001010111001 | Failed |
SHA-256 / 47ccf4ad9cb8ed3ac678664796587e92dc2e46087e6478be918e52cd73ffcfdf
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) != 2 or not all(c in '0123456789' for c in s):
return None
L = ['0001101', '0011001', '0010011', '0111101', '0100011', '0110001', '0101111', '0111011', '0110111', '0001011']
G = ['0100111', '0110011', '0011011', '0100001', '0011101', '0111001', '0000101', '0010001', '0001001', '0010111']
par = ['LL', 'LG', 'GL', 'GG'][int(s[1]) % 4]
a = (L if par[0] == 'L' else G)[int(s[0])]
b = (L if par[1] == 'L' else G)[int(s[1])]
return '1011' + a + '01' + b
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['73', '10110111011010100001'], ['30', '10110100001010001101'], ['42', '10110011101010010011'], ['05', '10110001101010111001'], ['08', '10110001101010110111'], ['06', '10110100111010101111'], ['49', '10110100011010010111'], ['55', '10110111001010111001']], [['19', '10110110011010010111'], ['98', '10110010111010110111'], ['96', '10110001011010101111'], ['44', '10110100011010100011'], ['47', '10110011101010010001'], ['08', '10110001101010110111'], ['06', '10110100111010101111'], ['22', '10110011011010010011']], [['38', '10110100001010110111'], ['73', '10110111011010100001'], ['88', '10110110111010110111'], ['87', '10110001001010010001'], ['83', '10110001001010100001'], ['02', '10110100111010010011'], ['85', '10110110111010111001'], ['17', '10110011001010010001']], [['66', '10110000101010101111'], ['77', '10110111011010010001'], ['92', '10110001011010010011'], ['40', '10110100011010001101'], ['84', '10110110111010100011'], ['49', '10110100011010010111'], ['89', '10110110111010010111'], ['13', '10110011001010100001']], [['52', '10110110001010010011'], ['50', '10110111001010001101'], ['16', '10110011001010101111'], ['85', '10110110111010111001'], ['43', '10110011101010100001'], ['89', '10110110111010010111'], ['48', '10110100011010110111'], ['29', '10110010011010010111']]]
labels = ["regression: parity selector value", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("%s %d" % (labels[i % len(labels)], i), 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: parity selector value 0 | 10110010001010100001 | 10110111011010100001 | Failed |
| repair trap 1 | 10110111101010001101 | 10110100001010001101 | Failed |
| combined fault 2 | 10110011101010010011 | 10110011101010010011 | Passed |
| control 3 | 10110001101010111001 | 10110001101010111001 | Passed |
| control 4 | 10110001101010110111 | 10110001101010110111 | Passed |
| boundary 5 | 10110100111010101111 | 10110100111010101111 | Passed |
| boundary 6 | 10110100011010010111 | 10110100011010010111 | Passed |
| control 7 | 10110110001010111001 | 10110111001010111001 | Failed |
SHA-256 / 991ded1672d299d116cde60872dd2098ee4abccf60c5733d7e71a5e2032f4f88
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) != 2 or not all(c in '0123456789' for c in s):
return None
L = ['0001101', '0011001', '0010011', '0111101', '0100011', '0110001', '0101111', '0111011', '0110111', '0001011']
G = ['0100111', '0110011', '0011011', '0100001', '0011101', '0111001', '0000101', '0010001', '0001001', '0010111']
par = ['LL', 'LG', 'GL', 'GG'][int(s) % 4]
a = (L if par[0] == 'L' else G)[int(s[0])]
b = (L if par[1] == 'L' else G)[int(s[1])]
return '1011' + a + '01' + b
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['73', '10110111011010100001'], ['30', '10110100001010001101'], ['42', '10110011101010010011'], ['05', '10110001101010111001'], ['08', '10110001101010110111'], ['06', '10110100111010101111'], ['49', '10110100011010010111'], ['55', '10110111001010111001']], [['19', '10110110011010010111'], ['98', '10110010111010110111'], ['96', '10110001011010101111'], ['44', '10110100011010100011'], ['47', '10110011101010010001'], ['08', '10110001101010110111'], ['06', '10110100111010101111'], ['22', '10110011011010010011']], [['38', '10110100001010110111'], ['73', '10110111011010100001'], ['88', '10110110111010110111'], ['87', '10110001001010010001'], ['83', '10110001001010100001'], ['02', '10110100111010010011'], ['85', '10110110111010111001'], ['17', '10110011001010010001']], [['66', '10110000101010101111'], ['77', '10110111011010010001'], ['92', '10110001011010010011'], ['40', '10110100011010001101'], ['84', '10110110111010100011'], ['49', '10110100011010010111'], ['89', '10110110111010010111'], ['13', '10110011001010100001']], [['52', '10110110001010010011'], ['50', '10110111001010001101'], ['16', '10110011001010101111'], ['85', '10110110111010111001'], ['43', '10110011101010100001'], ['89', '10110110111010010111'], ['48', '10110100011010110111'], ['29', '10110010011010010111']]]
labels = ["regression: parity selector value", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("%s %d" % (labels[i % len(labels)], i), 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: parity selector value 0 | 10110111011010100001 | 10110111011010100001 | Passed |
| repair trap 1 | 10110100001010001101 | 10110100001010001101 | Passed |
| combined fault 2 | 10110011101010010011 | 10110011101010010011 | Passed |
| control 3 | 10110001101010111001 | 10110001101010111001 | Passed |
| control 4 | 10110001101010110111 | 10110001101010110111 | Passed |
| boundary 5 | 10110100111010101111 | 10110100111010101111 | Passed |
| boundary 6 | 10110100011010010111 | 10110100011010010111 | Passed |
| control 7 | 10110111001010111001 | 10110111001010111001 | Passed |
SHA-256 / d67588bcb1109dd1ab5b9383cd5b05f7e65d6f558869c01c8550ca0212aef4d6
Verification & scope
A deterministic bounded teaching model with a stipulated contract; it makes no claim of conformance to any published specification. 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:49:47.025760+00:00.
Case digest / 52e32443eb32c617a13fe9852cb12bfeaa95071d927c030c6ae38491a24067e5