FA-79451 / Barcode symbology encoding / Open access
Leading FNC1 is emitted without a start character · case 01
GS1 symbols begin with value 102 and no start code, so scanners reject them.
ROOT CAUSE
A FNC1 before any set segment silently assumes set B without emitting its start.
VERIFIED REPAIR
Report no-start when FNC1 appears before any set segment.
Unsuccessful approach: Emitting a start C without recording the current set duplicates the start on the next segment.
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:
cur = 'B'
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 = [[[[['FNC1'], ['B', 'Lot 7'], ['A', '\x00Q']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', 'z'], ['C', '123']], {'error': 'no-start'}], [[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['B', '{x}'], ['SHIFT', '\t'], ['C', '1'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['C', '123'], ['FNC1']], {'error': 'bad-c'}], [[['FNC1'], ['A', '\t']], {'error': 'no-start'}]], [[[['FNC1'], ['B', 'z~'], ['B', 'Q'], ['FNC1'], ['A', '\x00Q']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', 'a']], {'error': 'no-start'}], [[['C', '1'], ['C', '12']], {'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'}], [[['FNC1'], ['B', 'Lot 7']], {'error': 'no-start'}]], [[[['FNC1'], ['SHIFT', 'a'], ['C', '1'], ['FNC1']], {'error': 'no-start'}], [[['FNC1'], ['B', 'z~']], {'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]], [[['C', '12']], [105, 12]], [[['FNC1'], ['FNC1'], ['A', 'HELLO'], ['C', '4711']], {'error': 'no-start'}]], [[[['FNC1'], ['SHIFT', 'z'], ['FNC1']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', 'B']], {'error': 'no-start'}], [[['B', 'Lot 7'], ['C', ' 1'], ['A', 'AB'], ['B', 'ab']], {'error': 'bad-c'}], [[['C', '4711'], ['B', 'ab'], ['A', 'X\x1d1']], [105, 47, 11, 100, 65, 66, 101, 56, 93, 17]], [[['B', 'z~']], [104, 90, 94]], [[['C', ' 1'], ['FNC1'], ['C', ' 1'], ['A', '_^']], {'error': 'bad-c'}], [[['C', ' 1'], ['C', '0099']], {'error': 'bad-c'}], [[['FNC1'], ['A', '\t'], ['A', 'A`']], {'error': 'no-start'}]], [[[['FNC1'], ['SHIFT', '\x1d'], ['B', 'z~'], ['A', 'AB']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', '\x1d']], {'error': 'no-start'}], [[['B', 'Q']], [104, 49]], [[['A', '\t'], ['C', '0099']], [103, 73, 99, 0, 99]], [[['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'}]]]
labels = ["regression: FNC1 before a start character", "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: FNC1 before a start character 0 | [102, 44, 79, 84, 0, 23, 101, 64, 49] | {'error': 'no-start'} | Failed |
| repair trap 1 | {'char': 'z', 'error': 'unencodable'} | {'error': 'no-start'} | Failed |
| combined fault 2 | [105, 12, 101, 40, 37, 44, 44, 47] | [105, 12, 101, 40, 37, 44, 44, 47] | Passed |
| control 3 | {'error': 'bad-c'} | {'error': 'bad-c'} | Passed |
| control 4 | {'error': 'bad-c'} | {'error': 'bad-c'} | Passed |
| boundary 5 | {'char': '\t', 'error': 'unencodable'} | {'char': '\t', 'error': 'unencodable'} | Passed |
| boundary 6 | {'error': 'bad-c'} | {'error': 'bad-c'} | Passed |
| control 7 | [102, 101, 73] | {'error': 'no-start'} | Failed |
SHA-256 / 26b23c9c3387a7061b10f85d71ba81ab92660654c3a5c88feb34d927b2d3c5eb
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:
out.append(105)
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 = [[[[['FNC1'], ['B', 'Lot 7'], ['A', '\x00Q']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', 'z'], ['C', '123']], {'error': 'no-start'}], [[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['B', '{x}'], ['SHIFT', '\t'], ['C', '1'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['C', '123'], ['FNC1']], {'error': 'bad-c'}], [[['FNC1'], ['A', '\t']], {'error': 'no-start'}]], [[[['FNC1'], ['B', 'z~'], ['B', 'Q'], ['FNC1'], ['A', '\x00Q']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', 'a']], {'error': 'no-start'}], [[['C', '1'], ['C', '12']], {'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'}], [[['FNC1'], ['B', 'Lot 7']], {'error': 'no-start'}]], [[[['FNC1'], ['SHIFT', 'a'], ['C', '1'], ['FNC1']], {'error': 'no-start'}], [[['FNC1'], ['B', 'z~']], {'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]], [[['C', '12']], [105, 12]], [[['FNC1'], ['FNC1'], ['A', 'HELLO'], ['C', '4711']], {'error': 'no-start'}]], [[[['FNC1'], ['SHIFT', 'z'], ['FNC1']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', 'B']], {'error': 'no-start'}], [[['B', 'Lot 7'], ['C', ' 1'], ['A', 'AB'], ['B', 'ab']], {'error': 'bad-c'}], [[['C', '4711'], ['B', 'ab'], ['A', 'X\x1d1']], [105, 47, 11, 100, 65, 66, 101, 56, 93, 17]], [[['B', 'z~']], [104, 90, 94]], [[['C', ' 1'], ['FNC1'], ['C', ' 1'], ['A', '_^']], {'error': 'bad-c'}], [[['C', ' 1'], ['C', '0099']], {'error': 'bad-c'}], [[['FNC1'], ['A', '\t'], ['A', 'A`']], {'error': 'no-start'}]], [[[['FNC1'], ['SHIFT', '\x1d'], ['B', 'z~'], ['A', 'AB']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', '\x1d']], {'error': 'no-start'}], [[['B', 'Q']], [104, 49]], [[['A', '\t'], ['C', '0099']], [103, 73, 99, 0, 99]], [[['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'}]]]
labels = ["regression: FNC1 before a start character", "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: FNC1 before a start character 0 | [105, 102, 104, 44, 79, 84, 0, 23, 101, 64, 49] | {'error': 'no-start'} | Failed |
| repair trap 1 | {'error': 'bad-shift'} | {'error': 'no-start'} | Failed |
| combined fault 2 | [105, 12, 101, 40, 37, 44, 44, 47] | [105, 12, 101, 40, 37, 44, 44, 47] | Passed |
| control 3 | {'error': 'bad-c'} | {'error': 'bad-c'} | Passed |
| control 4 | {'error': 'bad-c'} | {'error': 'bad-c'} | Passed |
| boundary 5 | {'char': '\t', 'error': 'unencodable'} | {'char': '\t', 'error': 'unencodable'} | Passed |
| boundary 6 | {'error': 'bad-c'} | {'error': 'bad-c'} | Passed |
| control 7 | [105, 102, 103, 73] | {'error': 'no-start'} | Failed |
SHA-256 / 226b1973f1a15de002599ed666c1c57c07a016e23da440dae7761ae663f89495
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 = [[[[['FNC1'], ['B', 'Lot 7'], ['A', '\x00Q']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', 'z'], ['C', '123']], {'error': 'no-start'}], [[['C', '12'], ['A', 'HELLO']], [105, 12, 101, 40, 37, 44, 44, 47]], [[['B', 'Q'], ['B', '{x}'], ['C', '123']], {'error': 'bad-c'}], [[['B', '{x}'], ['SHIFT', '\t'], ['C', '1'], ['A', '\x00Q']], {'error': 'bad-c'}], [[['B', 'ab'], ['A', '\x00Q'], ['SHIFT', '\t'], ['FNC1']], {'error': 'unencodable', 'char': '\t'}], [[['C', '123'], ['FNC1']], {'error': 'bad-c'}], [[['FNC1'], ['A', '\t']], {'error': 'no-start'}]], [[[['FNC1'], ['B', 'z~'], ['B', 'Q'], ['FNC1'], ['A', '\x00Q']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', 'a']], {'error': 'no-start'}], [[['C', '1'], ['C', '12']], {'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'}], [[['FNC1'], ['B', 'Lot 7']], {'error': 'no-start'}]], [[[['FNC1'], ['SHIFT', 'a'], ['C', '1'], ['FNC1']], {'error': 'no-start'}], [[['FNC1'], ['B', 'z~']], {'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]], [[['C', '12']], [105, 12]], [[['FNC1'], ['FNC1'], ['A', 'HELLO'], ['C', '4711']], {'error': 'no-start'}]], [[[['FNC1'], ['SHIFT', 'z'], ['FNC1']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', 'B']], {'error': 'no-start'}], [[['B', 'Lot 7'], ['C', ' 1'], ['A', 'AB'], ['B', 'ab']], {'error': 'bad-c'}], [[['C', '4711'], ['B', 'ab'], ['A', 'X\x1d1']], [105, 47, 11, 100, 65, 66, 101, 56, 93, 17]], [[['B', 'z~']], [104, 90, 94]], [[['C', ' 1'], ['FNC1'], ['C', ' 1'], ['A', '_^']], {'error': 'bad-c'}], [[['C', ' 1'], ['C', '0099']], {'error': 'bad-c'}], [[['FNC1'], ['A', '\t'], ['A', 'A`']], {'error': 'no-start'}]], [[[['FNC1'], ['SHIFT', '\x1d'], ['B', 'z~'], ['A', 'AB']], {'error': 'no-start'}], [[['FNC1'], ['SHIFT', '\x1d']], {'error': 'no-start'}], [[['B', 'Q']], [104, 49]], [[['A', '\t'], ['C', '0099']], [103, 73, 99, 0, 99]], [[['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'}]]]
labels = ["regression: FNC1 before a start character", "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: FNC1 before a start character 0 | {'error': 'no-start'} | {'error': 'no-start'} | Passed |
| repair trap 1 | {'error': 'no-start'} | {'error': 'no-start'} | Passed |
| combined fault 2 | [105, 12, 101, 40, 37, 44, 44, 47] | [105, 12, 101, 40, 37, 44, 44, 47] | Passed |
| control 3 | {'error': 'bad-c'} | {'error': 'bad-c'} | Passed |
| control 4 | {'error': 'bad-c'} | {'error': 'bad-c'} | Passed |
| boundary 5 | {'char': '\t', 'error': 'unencodable'} | {'char': '\t', 'error': 'unencodable'} | Passed |
| boundary 6 | {'error': 'bad-c'} | {'error': 'bad-c'} | Passed |
| control 7 | {'error': 'no-start'} | {'error': 'no-start'} | Passed |
SHA-256 / 750880576bf7a4598385d9806dca33a31d7bf0b5bc5d5cea3f95f11288721f8a
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.648679+00:00.
Case digest / 6958145c976d0681415a03b392f08e3e4dac45ee0c8e16aa1c92316355cfa75a