FA-72746 / Check-digit algorithms / Open access
CPF second check digit reuses the first weight range · case 01
Most valid CPFs fail the second check digit.
ROOT CAUSE
k2 is weighted 10..2, so zip truncates the list and the computed k1 never enters the sum.
VERIFIED REPAIR
Weight the ten digits for k2 by 11 down to 2.
Unsuccessful approach: Shifting the range to 12..3 covers ten digits but with every weight one too large.
Case contract
Brazilian CPF taxpayer number: dots and hyphens removed, then 11 ASCII digits that are not all the same digit (else "malformed"). k1 = (sum of digits 1-9 weighted 10..2) * 10 mod 11 mod 10; k2 = (digits 1-9 and the computed k1 weighted 11..2) * 10 mod 11 mod 10. Return [k1, k2, whether digits 10-11 equal them].
Why this case matters
Onboarding and invoicing flows validate CPF numbers before tax reporting.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(s):
t = s.replace('.', '').replace('-', '')
if len(t) != 11 or not t.isascii() or not t.isdigit():
return 'malformed'
if len(set(t)) == 1:
return 'malformed'
d = [int(ch) for ch in t]
k1 = sum(w * x for w, x in zip(range(10, 1, -1), d[:9])) * 10 % 11 % 10
k2 = sum(w * x for w, x in zip(range(10, 1, -1), d[:9] + [k1])) * 10 % 11 % 10
return [k1, k2, d[9] == k1 and d[10] == k2]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression ["42765277574"]', ['42765277574'], [9, 1, False]], ['regression ["04160821863"]', ['04160821863'], [1, 2, False]], ['control ["111.111.111-11"]', ['111.111.111-11'], 'malformed'], ['control ["00000000000"]', ['00000000000'], 'malformed'], ['control ["22222222222"]', ['22222222222'], 'malformed'], ['control ["1234567890"]', ['1234567890'], 'malformed'], ['control ["80112861152"]', ['80112861152'], [0, 5, False]], ['control ["61682621036"]', ['61682621036'], [5, 7, False]]], [['regression ["54166960081"]', ['54166960081'], [1, 6, False]], ['regression ["80112861152"]', ['80112861152'], [0, 5, False]], ['control ["00000000000"]', ['00000000000'], 'malformed'], ['control ["22222222222"]', ['22222222222'], 'malformed'], ['control ["1234567890"]', ['1234567890'], 'malformed'], ['control ["111.111.111-11"]', ['111.111.111-11'], 'malformed'], ['control ["11888021888"]', ['11888021888'], [6, 1, False]], ['control ["02970275879"]', ['02970275879'], [1, 3, False]]], [['regression ["91615291602"]', ['91615291602'], [8, 7, False]], ['regression ["38203173222"]', ['38203173222'], [5, 0, False]], ['control ["22222222222"]', ['22222222222'], 'malformed'], ['control ["1234567890"]', ['1234567890'], 'malformed'], ['control ["111.111.111-11"]', ['111.111.111-11'], 'malformed'], ['control ["00000000000"]', ['00000000000'], 'malformed'], ['control ["25998738965"]', ['25998738965'], [4, 2, False]], ['control ["52682522850"]', ['52682522850'], [3, 1, False]]], [['regression ["11888021888"]', ['11888021888'], [6, 1, False]], ['regression ["02970275879"]', ['02970275879'], [1, 3, False]], ['control ["1234567890"]', ['1234567890'], 'malformed'], ['control ["111.111.111-11"]', ['111.111.111-11'], 'malformed'], ['control ["00000000000"]', ['00000000000'], 'malformed'], ['control ["22222222222"]', ['22222222222'], 'malformed'], ['control ["37134793981"]', ['37134793981'], [9, 0, False]], ['control ["529.982.247-25"]', ['529.982.247-25'], [2, 5, True]]], [['regression ["29622049718"]', ['29622049718'], [0, 2, False]], ['regression ["22747397622"]', ['22747397622'], [5, 3, False]], ['control ["111.111.111-11"]', ['111.111.111-11'], 'malformed'], ['control ["00000000000"]', ['00000000000'], 'malformed'], ['control ["22222222222"]', ['22222222222'], 'malformed'], ['control ["1234567890"]', ['1234567890'], 'malformed'], ['control ["123.456.789-09"]', ['123.456.789-09'], [0, 9, True]], ['control ["123.456.789-00"]', ['123.456.789-00'], [0, 9, 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 ["42765277574"] | [9, 9, False] | [9, 1, False] | Failed |
| regression ["04160821863"] | [1, 1, False] | [1, 2, False] | Failed |
| control ["111.111.111-11"] | malformed | malformed | Passed |
| control ["00000000000"] | malformed | malformed | Passed |
| control ["22222222222"] | malformed | malformed | Passed |
| control ["1234567890"] | malformed | malformed | Passed |
| control ["80112861152"] | [0, 0, False] | [0, 5, False] | Failed |
| control ["61682621036"] | [5, 5, False] | [5, 7, False] | Failed |
SHA-256 / 396899f8dfd2fe2211390987409830d29f18cbb3e3030bb76c5415c8e771d71a
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(s):
t = s.replace('.', '').replace('-', '')
if len(t) != 11 or not t.isascii() or not t.isdigit():
return 'malformed'
if len(set(t)) == 1:
return 'malformed'
d = [int(ch) for ch in t]
k1 = sum(w * x for w, x in zip(range(10, 1, -1), d[:9])) * 10 % 11 % 10
k2 = sum(w * x for w, x in zip(range(12, 2, -1), d[:9] + [k1])) * 10 % 11 % 10
return [k1, k2, d[9] == k1 and d[10] == k2]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression ["42765277574"]', ['42765277574'], [9, 1, False]], ['regression ["04160821863"]', ['04160821863'], [1, 2, False]], ['control ["111.111.111-11"]', ['111.111.111-11'], 'malformed'], ['control ["00000000000"]', ['00000000000'], 'malformed'], ['control ["22222222222"]', ['22222222222'], 'malformed'], ['control ["1234567890"]', ['1234567890'], 'malformed'], ['control ["80112861152"]', ['80112861152'], [0, 5, False]], ['control ["61682621036"]', ['61682621036'], [5, 7, False]]], [['regression ["54166960081"]', ['54166960081'], [1, 6, False]], ['regression ["80112861152"]', ['80112861152'], [0, 5, False]], ['control ["00000000000"]', ['00000000000'], 'malformed'], ['control ["22222222222"]', ['22222222222'], 'malformed'], ['control ["1234567890"]', ['1234567890'], 'malformed'], ['control ["111.111.111-11"]', ['111.111.111-11'], 'malformed'], ['control ["11888021888"]', ['11888021888'], [6, 1, False]], ['control ["02970275879"]', ['02970275879'], [1, 3, False]]], [['regression ["91615291602"]', ['91615291602'], [8, 7, False]], ['regression ["38203173222"]', ['38203173222'], [5, 0, False]], ['control ["22222222222"]', ['22222222222'], 'malformed'], ['control ["1234567890"]', ['1234567890'], 'malformed'], ['control ["111.111.111-11"]', ['111.111.111-11'], 'malformed'], ['control ["00000000000"]', ['00000000000'], 'malformed'], ['control ["25998738965"]', ['25998738965'], [4, 2, False]], ['control ["52682522850"]', ['52682522850'], [3, 1, False]]], [['regression ["11888021888"]', ['11888021888'], [6, 1, False]], ['regression ["02970275879"]', ['02970275879'], [1, 3, False]], ['control ["1234567890"]', ['1234567890'], 'malformed'], ['control ["111.111.111-11"]', ['111.111.111-11'], 'malformed'], ['control ["00000000000"]', ['00000000000'], 'malformed'], ['control ["22222222222"]', ['22222222222'], 'malformed'], ['control ["37134793981"]', ['37134793981'], [9, 0, False]], ['control ["529.982.247-25"]', ['529.982.247-25'], [2, 5, True]]], [['regression ["29622049718"]', ['29622049718'], [0, 2, False]], ['regression ["22747397622"]', ['22747397622'], [5, 3, False]], ['control ["111.111.111-11"]', ['111.111.111-11'], 'malformed'], ['control ["00000000000"]', ['00000000000'], 'malformed'], ['control ["22222222222"]', ['22222222222'], 'malformed'], ['control ["1234567890"]', ['1234567890'], 'malformed'], ['control ["123.456.789-09"]', ['123.456.789-09'], [0, 9, True]], ['control ["123.456.789-00"]', ['123.456.789-00'], [0, 9, 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 ["42765277574"] | [9, 2, False] | [9, 1, False] | Failed |
| regression ["04160821863"] | [1, 4, False] | [1, 2, False] | Failed |
| control ["111.111.111-11"] | malformed | malformed | Passed |
| control ["00000000000"] | malformed | malformed | Passed |
| control ["22222222222"] | malformed | malformed | Passed |
| control ["1234567890"] | malformed | malformed | Passed |
| control ["80112861152"] | [0, 0, False] | [0, 5, False] | Failed |
| control ["61682621036"] | [5, 3, False] | [5, 7, False] | Failed |
SHA-256 / 61825751349d90752bf5e2f7653425a153c6aec18d5048a6652d5abf8b90a0a7
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(s):
t = s.replace('.', '').replace('-', '')
if len(t) != 11 or not t.isascii() or not t.isdigit():
return 'malformed'
if len(set(t)) == 1:
return 'malformed'
d = [int(ch) for ch in t]
k1 = sum(w * x for w, x in zip(range(10, 1, -1), d[:9])) * 10 % 11 % 10
k2 = sum(w * x for w, x in zip(range(11, 1, -1), d[:9] + [k1])) * 10 % 11 % 10
return [k1, k2, d[9] == k1 and d[10] == k2]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression ["42765277574"]', ['42765277574'], [9, 1, False]], ['regression ["04160821863"]', ['04160821863'], [1, 2, False]], ['control ["111.111.111-11"]', ['111.111.111-11'], 'malformed'], ['control ["00000000000"]', ['00000000000'], 'malformed'], ['control ["22222222222"]', ['22222222222'], 'malformed'], ['control ["1234567890"]', ['1234567890'], 'malformed'], ['control ["80112861152"]', ['80112861152'], [0, 5, False]], ['control ["61682621036"]', ['61682621036'], [5, 7, False]]], [['regression ["54166960081"]', ['54166960081'], [1, 6, False]], ['regression ["80112861152"]', ['80112861152'], [0, 5, False]], ['control ["00000000000"]', ['00000000000'], 'malformed'], ['control ["22222222222"]', ['22222222222'], 'malformed'], ['control ["1234567890"]', ['1234567890'], 'malformed'], ['control ["111.111.111-11"]', ['111.111.111-11'], 'malformed'], ['control ["11888021888"]', ['11888021888'], [6, 1, False]], ['control ["02970275879"]', ['02970275879'], [1, 3, False]]], [['regression ["91615291602"]', ['91615291602'], [8, 7, False]], ['regression ["38203173222"]', ['38203173222'], [5, 0, False]], ['control ["22222222222"]', ['22222222222'], 'malformed'], ['control ["1234567890"]', ['1234567890'], 'malformed'], ['control ["111.111.111-11"]', ['111.111.111-11'], 'malformed'], ['control ["00000000000"]', ['00000000000'], 'malformed'], ['control ["25998738965"]', ['25998738965'], [4, 2, False]], ['control ["52682522850"]', ['52682522850'], [3, 1, False]]], [['regression ["11888021888"]', ['11888021888'], [6, 1, False]], ['regression ["02970275879"]', ['02970275879'], [1, 3, False]], ['control ["1234567890"]', ['1234567890'], 'malformed'], ['control ["111.111.111-11"]', ['111.111.111-11'], 'malformed'], ['control ["00000000000"]', ['00000000000'], 'malformed'], ['control ["22222222222"]', ['22222222222'], 'malformed'], ['control ["37134793981"]', ['37134793981'], [9, 0, False]], ['control ["529.982.247-25"]', ['529.982.247-25'], [2, 5, True]]], [['regression ["29622049718"]', ['29622049718'], [0, 2, False]], ['regression ["22747397622"]', ['22747397622'], [5, 3, False]], ['control ["111.111.111-11"]', ['111.111.111-11'], 'malformed'], ['control ["00000000000"]', ['00000000000'], 'malformed'], ['control ["22222222222"]', ['22222222222'], 'malformed'], ['control ["1234567890"]', ['1234567890'], 'malformed'], ['control ["123.456.789-09"]', ['123.456.789-09'], [0, 9, True]], ['control ["123.456.789-00"]', ['123.456.789-00'], [0, 9, 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 ["42765277574"] | [9, 1, False] | [9, 1, False] | Passed |
| regression ["04160821863"] | [1, 2, False] | [1, 2, False] | Passed |
| control ["111.111.111-11"] | malformed | malformed | Passed |
| control ["00000000000"] | malformed | malformed | Passed |
| control ["22222222222"] | malformed | malformed | Passed |
| control ["1234567890"] | malformed | malformed | Passed |
| control ["80112861152"] | [0, 5, False] | [0, 5, False] | Passed |
| control ["61682621036"] | [5, 7, False] | [5, 7, False] | Passed |
SHA-256 / 8b68f9592b26610bb9eb66e58ded17f85cb2bcd0301d03f06143a56c7938f08a
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:41.173861+00:00.
Case digest / 32c91633e4eef1832eb60c7bb0add5e8ea82913e8996483358aa25912027980d