FA-79446 / Barcode symbology encoding / Open access
Set C accepts pairs containing spaces · case 01
A space-padded quantity is encoded as a digit pair value because int() ignores whitespace.
ROOT CAUSE
Only the length parity is checked before converting pairs with int().
VERIFIED REPAIR
Require even length and ASCII digits only.
Unsuccessful approach: Checking isdigit without the parity lets an odd final digit become a single-digit pair.
Case contract
Turn planned Code 128 segments into symbol values (without the checksum). Segments are [set, text], ["FNC1"] or ["SHIFT", char]. The first set segment emits its start (A 103, B 104, C 105); later set changes emit Code A 101, Code B 100 or Code C 99. Set A encodes 32..95 as ord-32 and 0..31 as ord+64; set B encodes 32..127 as ord-32; set C encodes even-length ASCII digit text as pair values. FNC1 is 102 and needs a prior start; SHIFT (98) is only valid in A or B and encodes one character in the other of A/B. Errors: no-start, bad-shift, bad-c, unencodable.
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(segs):
out = []
cur = None
starts = {'A': 103, 'B': 104, 'C': 105}
switch = {'A': 101, 'B': 100, 'C': 99}
def val(s, ch):
o = ord(ch)
if s == 'A':
if 32 <= o <= 95:
return o - 32
if 0 <= o <= 31:
return o + 64
return None
if 32 <= o <= 127:
return o - 32
return None
for seg in segs:
kind = seg[0]
if kind == 'FNC1':
if cur is None:
return {'error': 'no-start'}
out.append(102)
continue
if kind == 'SHIFT':
if cur not in ('A', 'B'):
return {'error': 'bad-shift'}
other = 'B' if cur == 'A' else 'A'
v = val(other, seg[1])
if v is None:
return {'error': 'unencodable', 'char': seg[1]}
out += [98, v]
continue
s, text = seg
if cur is None:
out.append(starts[s])
elif s != cur:
out.append(switch[s])
cur = s
if s == 'C':
if len(text) % 2:
return {'error': 'bad-c'}
out += [int(text[j:j + 2]) for j in range(0, len(text), 2)]
else:
for ch in text:
v = val(s, ch)
if v is None:
return {'error': 'unencodable', 'char': ch}
out.append(v)
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['B', 'Lot 7'], ['C', '12'], ['C', ' 1']], {'error': 'bad-c'}], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['B', 'Lot 7'], ['A', '\x00Q'], ['FNC1'], ['C', '4711']], [104, 44, 79, 84, 0, 23, 101, 64, 49, 102, 99, 47, 11]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['A', 'HELLO'], ['A', 'AB'], ['A', 'X\x1d1']], [103, 40, 37, 44, 44, 47, 33, 34, 56, 93, 17]], [[['B', '{x}'], ['A', 'X\x1d1'], ['C', ' 1'], ['SHIFT', '\x1d']], {'error': 'bad-c'}]], [[[['C', ' 1'], ['FNC1']], {'error': 'bad-c'}], [[['A', '\t'], ['C', '0099'], ['A', 'HELLO'], ['C', '123']], {'error': 'bad-c'}], [[['A', '\x00Q'], ['B', '{x}'], ['A', 'X\x1d1'], ['SHIFT', 'z']], [103, 64, 49, 100, 91, 88, 93, 101, 56, 93, 17, 98, 90]], [[['A', 'AB'], ['B', 'Q'], ['B', 'z~']], [103, 33, 34, 100, 49, 90, 94]], [[['A', 'AB'], ['FNC1']], [103, 33, 34, 102]], [[['B', 'z~'], ['SHIFT', 'z'], ['FNC1']], {'error': 'unencodable', 'char': 'z'}], [[['B', '{x}'], ['A', '_^']], [104, 91, 88, 93, 101, 63, 62]], [[['C', ' 1'], ['A', '\x00Q'], ['FNC1'], ['B', '{x}']], {'error': 'bad-c'}]], [[[['C', ' 1']], {'error': 'bad-c'}], [[['C', '123'], ['A', 'AB'], ['A', '\t'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['FNC1'], ['C', '0099'], ['B', 'Lot 7'], ['C', '4711'], ['C', '12']], {'error': 'no-start'}], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['C', '0099']], [105, 0, 99]], [[['A', 'AB']], [103, 33, 34]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['B', '{x}'], ['C', ' 1']], {'error': 'bad-c'}]], [[[['C', ' 1'], ['C', '0099']], {'error': 'bad-c'}], [[['B', '{x}'], ['C', '123'], ['C', '0099']], {'error': 'bad-c'}], [[['B', 'z~']], [104, 90, 94]], [[['C', '4711']], [105, 47, 11]], [[['A', 'HELLO'], ['A', '_^'], ['A', '_^']], [103, 40, 37, 44, 44, 47, 63, 62, 63, 62]], [[['A', '\t']], [103, 73]], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['B', 'Lot 7'], ['C', ' 1'], ['A', 'AB'], ['B', 'ab']], {'error': 'bad-c'}]], [[[['B', 'ab'], ['C', ' 1']], {'error': 'bad-c'}], [[['C', '0099'], ['C', '123']], {'error': 'bad-c'}], [[['FNC1'], ['A', 'HELLO']], {'error': 'no-start'}], [[['C', '4711'], ['B', 'Q'], ['B', '{x}']], [105, 47, 11, 100, 49, 91, 88, 93]], [[['B', '{x}'], ['B', 'Q']], [104, 91, 88, 93, 49]], [[['A', 'AB']], [103, 33, 34]], [[['FNC1'], ['A', 'X\x1d1']], {'error': 'no-start'}], [[['C', ' 1'], ['A', '_^'], ['SHIFT', '\x1d']], {'error': 'bad-c'}]]]
labels = ["regression: set C text validation", "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: set C text validation 0 | [104, 44, 79, 84, 0, 23, 99, 12, 1] | {'error': 'bad-c'} | Failed |
| repair trap 1 | {'error': 'bad-c'} | {'error': 'bad-c'} | Passed |
| combined fault 2 | [105, 12, 101, 40, 37, 44, 44, 47] | [105, 12, 101, 40, 37, 44, 44, 47] | Passed |
| control 3 | {'char': '\t', 'error': 'unencodable'} | {'char': '\t', 'error': 'unencodable'} | Passed |
| control 4 | [104, 44, 79, 84, 0, 23, 101, 64, 49, 102, 99, 47, 11] | [104, 44, 79, 84, 0, 23, 101, 64, 49, 102, 99, 47, 11] | Passed |
| boundary 5 | [103, 56, 93, 17] | [103, 56, 93, 17] | Passed |
| boundary 6 | [103, 40, 37, 44, 44, 47, 33, 34, 56, 93, 17] | [103, 40, 37, 44, 44, 47, 33, 34, 56, 93, 17] | Passed |
| control 7 | {'error': 'bad-shift'} | {'error': 'bad-c'} | Failed |
SHA-256 / ce74fb8d8fbd6ed60c92d6911de93271339f540eca8474e2c2d648f79d5188d9
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(segs):
out = []
cur = None
starts = {'A': 103, 'B': 104, 'C': 105}
switch = {'A': 101, 'B': 100, 'C': 99}
def val(s, ch):
o = ord(ch)
if s == 'A':
if 32 <= o <= 95:
return o - 32
if 0 <= o <= 31:
return o + 64
return None
if 32 <= o <= 127:
return o - 32
return None
for seg in segs:
kind = seg[0]
if kind == 'FNC1':
if cur is None:
return {'error': 'no-start'}
out.append(102)
continue
if kind == 'SHIFT':
if cur not in ('A', 'B'):
return {'error': 'bad-shift'}
other = 'B' if cur == 'A' else 'A'
v = val(other, seg[1])
if v is None:
return {'error': 'unencodable', 'char': seg[1]}
out += [98, v]
continue
s, text = seg
if cur is None:
out.append(starts[s])
elif s != cur:
out.append(switch[s])
cur = s
if s == 'C':
if not text.isdigit():
return {'error': 'bad-c'}
out += [int(text[j:j + 2]) for j in range(0, len(text), 2)]
else:
for ch in text:
v = val(s, ch)
if v is None:
return {'error': 'unencodable', 'char': ch}
out.append(v)
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['B', 'Lot 7'], ['C', '12'], ['C', ' 1']], {'error': 'bad-c'}], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['B', 'Lot 7'], ['A', '\x00Q'], ['FNC1'], ['C', '4711']], [104, 44, 79, 84, 0, 23, 101, 64, 49, 102, 99, 47, 11]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['A', 'HELLO'], ['A', 'AB'], ['A', 'X\x1d1']], [103, 40, 37, 44, 44, 47, 33, 34, 56, 93, 17]], [[['B', '{x}'], ['A', 'X\x1d1'], ['C', ' 1'], ['SHIFT', '\x1d']], {'error': 'bad-c'}]], [[[['C', ' 1'], ['FNC1']], {'error': 'bad-c'}], [[['A', '\t'], ['C', '0099'], ['A', 'HELLO'], ['C', '123']], {'error': 'bad-c'}], [[['A', '\x00Q'], ['B', '{x}'], ['A', 'X\x1d1'], ['SHIFT', 'z']], [103, 64, 49, 100, 91, 88, 93, 101, 56, 93, 17, 98, 90]], [[['A', 'AB'], ['B', 'Q'], ['B', 'z~']], [103, 33, 34, 100, 49, 90, 94]], [[['A', 'AB'], ['FNC1']], [103, 33, 34, 102]], [[['B', 'z~'], ['SHIFT', 'z'], ['FNC1']], {'error': 'unencodable', 'char': 'z'}], [[['B', '{x}'], ['A', '_^']], [104, 91, 88, 93, 101, 63, 62]], [[['C', ' 1'], ['A', '\x00Q'], ['FNC1'], ['B', '{x}']], {'error': 'bad-c'}]], [[[['C', ' 1']], {'error': 'bad-c'}], [[['C', '123'], ['A', 'AB'], ['A', '\t'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['FNC1'], ['C', '0099'], ['B', 'Lot 7'], ['C', '4711'], ['C', '12']], {'error': 'no-start'}], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['C', '0099']], [105, 0, 99]], [[['A', 'AB']], [103, 33, 34]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['B', '{x}'], ['C', ' 1']], {'error': 'bad-c'}]], [[[['C', ' 1'], ['C', '0099']], {'error': 'bad-c'}], [[['B', '{x}'], ['C', '123'], ['C', '0099']], {'error': 'bad-c'}], [[['B', 'z~']], [104, 90, 94]], [[['C', '4711']], [105, 47, 11]], [[['A', 'HELLO'], ['A', '_^'], ['A', '_^']], [103, 40, 37, 44, 44, 47, 63, 62, 63, 62]], [[['A', '\t']], [103, 73]], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['B', 'Lot 7'], ['C', ' 1'], ['A', 'AB'], ['B', 'ab']], {'error': 'bad-c'}]], [[[['B', 'ab'], ['C', ' 1']], {'error': 'bad-c'}], [[['C', '0099'], ['C', '123']], {'error': 'bad-c'}], [[['FNC1'], ['A', 'HELLO']], {'error': 'no-start'}], [[['C', '4711'], ['B', 'Q'], ['B', '{x}']], [105, 47, 11, 100, 49, 91, 88, 93]], [[['B', '{x}'], ['B', 'Q']], [104, 91, 88, 93, 49]], [[['A', 'AB']], [103, 33, 34]], [[['FNC1'], ['A', 'X\x1d1']], {'error': 'no-start'}], [[['C', ' 1'], ['A', '_^'], ['SHIFT', '\x1d']], {'error': 'bad-c'}]]]
labels = ["regression: set C text validation", "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: set C text validation 0 | {'error': 'bad-c'} | {'error': 'bad-c'} | Passed |
| repair trap 1 | [104, 49, 91, 88, 93, 99, 12, 3] | {'error': 'bad-c'} | Failed |
| combined fault 2 | [105, 12, 101, 40, 37, 44, 44, 47] | [105, 12, 101, 40, 37, 44, 44, 47] | Passed |
| control 3 | {'char': '\t', 'error': 'unencodable'} | {'char': '\t', 'error': 'unencodable'} | Passed |
| control 4 | [104, 44, 79, 84, 0, 23, 101, 64, 49, 102, 99, 47, 11] | [104, 44, 79, 84, 0, 23, 101, 64, 49, 102, 99, 47, 11] | Passed |
| boundary 5 | [103, 56, 93, 17] | [103, 56, 93, 17] | Passed |
| boundary 6 | [103, 40, 37, 44, 44, 47, 33, 34, 56, 93, 17] | [103, 40, 37, 44, 44, 47, 33, 34, 56, 93, 17] | Passed |
| control 7 | {'error': 'bad-c'} | {'error': 'bad-c'} | Passed |
SHA-256 / 2a82d253fbc1a8160560df6dc8a1eed35262a04c5dc60d465fc07849d258f757
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(segs):
out = []
cur = None
starts = {'A': 103, 'B': 104, 'C': 105}
switch = {'A': 101, 'B': 100, 'C': 99}
def val(s, ch):
o = ord(ch)
if s == 'A':
if 32 <= o <= 95:
return o - 32
if 0 <= o <= 31:
return o + 64
return None
if 32 <= o <= 127:
return o - 32
return None
for seg in segs:
kind = seg[0]
if kind == 'FNC1':
if cur is None:
return {'error': 'no-start'}
out.append(102)
continue
if kind == 'SHIFT':
if cur not in ('A', 'B'):
return {'error': 'bad-shift'}
other = 'B' if cur == 'A' else 'A'
v = val(other, seg[1])
if v is None:
return {'error': 'unencodable', 'char': seg[1]}
out += [98, v]
continue
s, text = seg
if cur is None:
out.append(starts[s])
elif s != cur:
out.append(switch[s])
cur = s
if s == 'C':
if len(text) % 2 or not all(c in '0123456789' for c in text):
return {'error': 'bad-c'}
out += [int(text[j:j + 2]) for j in range(0, len(text), 2)]
else:
for ch in text:
v = val(s, ch)
if v is None:
return {'error': 'unencodable', 'char': ch}
out.append(v)
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['B', 'Lot 7'], ['C', '12'], ['C', ' 1']], {'error': 'bad-c'}], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['B', 'Lot 7'], ['A', '\x00Q'], ['FNC1'], ['C', '4711']], [104, 44, 79, 84, 0, 23, 101, 64, 49, 102, 99, 47, 11]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['A', 'HELLO'], ['A', 'AB'], ['A', 'X\x1d1']], [103, 40, 37, 44, 44, 47, 33, 34, 56, 93, 17]], [[['B', '{x}'], ['A', 'X\x1d1'], ['C', ' 1'], ['SHIFT', '\x1d']], {'error': 'bad-c'}]], [[[['C', ' 1'], ['FNC1']], {'error': 'bad-c'}], [[['A', '\t'], ['C', '0099'], ['A', 'HELLO'], ['C', '123']], {'error': 'bad-c'}], [[['A', '\x00Q'], ['B', '{x}'], ['A', 'X\x1d1'], ['SHIFT', 'z']], [103, 64, 49, 100, 91, 88, 93, 101, 56, 93, 17, 98, 90]], [[['A', 'AB'], ['B', 'Q'], ['B', 'z~']], [103, 33, 34, 100, 49, 90, 94]], [[['A', 'AB'], ['FNC1']], [103, 33, 34, 102]], [[['B', 'z~'], ['SHIFT', 'z'], ['FNC1']], {'error': 'unencodable', 'char': 'z'}], [[['B', '{x}'], ['A', '_^']], [104, 91, 88, 93, 101, 63, 62]], [[['C', ' 1'], ['A', '\x00Q'], ['FNC1'], ['B', '{x}']], {'error': 'bad-c'}]], [[[['C', ' 1']], {'error': 'bad-c'}], [[['C', '123'], ['A', 'AB'], ['A', '\t'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['FNC1'], ['C', '0099'], ['B', 'Lot 7'], ['C', '4711'], ['C', '12']], {'error': 'no-start'}], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['C', '0099']], [105, 0, 99]], [[['A', 'AB']], [103, 33, 34]], [[['A', 'X\x1d1']], [103, 56, 93, 17]], [[['B', '{x}'], ['C', ' 1']], {'error': 'bad-c'}]], [[[['C', ' 1'], ['C', '0099']], {'error': 'bad-c'}], [[['B', '{x}'], ['C', '123'], ['C', '0099']], {'error': 'bad-c'}], [[['B', 'z~']], [104, 90, 94]], [[['C', '4711']], [105, 47, 11]], [[['A', 'HELLO'], ['A', '_^'], ['A', '_^']], [103, 40, 37, 44, 44, 47, 63, 62, 63, 62]], [[['A', '\t']], [103, 73]], [[['B', 'Lot 7']], [104, 44, 79, 84, 0, 23]], [[['B', 'Lot 7'], ['C', ' 1'], ['A', 'AB'], ['B', 'ab']], {'error': 'bad-c'}]], [[[['B', 'ab'], ['C', ' 1']], {'error': 'bad-c'}], [[['C', '0099'], ['C', '123']], {'error': 'bad-c'}], [[['FNC1'], ['A', 'HELLO']], {'error': 'no-start'}], [[['C', '4711'], ['B', 'Q'], ['B', '{x}']], [105, 47, 11, 100, 49, 91, 88, 93]], [[['B', '{x}'], ['B', 'Q']], [104, 91, 88, 93, 49]], [[['A', 'AB']], [103, 33, 34]], [[['FNC1'], ['A', 'X\x1d1']], {'error': 'no-start'}], [[['C', ' 1'], ['A', '_^'], ['SHIFT', '\x1d']], {'error': 'bad-c'}]]]
labels = ["regression: set C text validation", "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: set C text validation 0 | {'error': 'bad-c'} | {'error': 'bad-c'} | Passed |
| repair trap 1 | {'error': 'bad-c'} | {'error': 'bad-c'} | Passed |
| combined fault 2 | [105, 12, 101, 40, 37, 44, 44, 47] | [105, 12, 101, 40, 37, 44, 44, 47] | Passed |
| control 3 | {'char': '\t', 'error': 'unencodable'} | {'char': '\t', 'error': 'unencodable'} | Passed |
| control 4 | [104, 44, 79, 84, 0, 23, 101, 64, 49, 102, 99, 47, 11] | [104, 44, 79, 84, 0, 23, 101, 64, 49, 102, 99, 47, 11] | Passed |
| boundary 5 | [103, 56, 93, 17] | [103, 56, 93, 17] | Passed |
| boundary 6 | [103, 40, 37, 44, 44, 47, 33, 34, 56, 93, 17] | [103, 40, 37, 44, 44, 47, 33, 34, 56, 93, 17] | Passed |
| control 7 | {'error': 'bad-c'} | {'error': 'bad-c'} | Passed |
SHA-256 / 9e1a1e4c172cfad6937b365c254d7593b4eecd5af8fee3ef0fefee441143e08a
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:44.476151+00:00.
Case digest / 86d258fc733df7852c120684e43827d5f4eb1fc5690bfe518f336c089643b04b