{"abstract":"Numbers typed in lowercase are reported as mismatches or malformed.","category":"Check-digit algorithms","checks":8,"contract":"Spanish DNI/NIE control letter: input upper-cased, hyphens removed, then nine characters: eight digits (or X/Y/Z followed by seven digits, the prefix standing for 0/1/2) and a letter (else \"malformed\"). The letter is \"TRWAGMYFPDXBNJZSQVHLCKE\"[number mod 23]. Return [expected letter, match].","evaluation_group":"w2-check_digit_algorithms-es-dni-nie","failed_approach":"Upper-casing only the control letter leaves a lowercase NIE prefix unmapped.","family":"w2-check_digit_algorithms-es-dni-nie-case-normalization","id":"FA-72826","implementations":{"attempt":{"sha256":"4f9061909ab90af06ece138e3e2cf38c3d54961bc5d240ea1ee5e0c43e62933a","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(s):\n    t = s.replace('-', '')\n    if len(t) != 9 or not t.isascii():\n        return 'malformed'\n    body = t[:8]\n    if body[0] in 'XYZ':\n        body = str('XYZ'.index(body[0])) + body[1:]\n    if not body.isdigit() or not t[8].isalpha():\n        return 'malformed'\n    letter = 'TRWAGMYFPDXBNJZSQVHLCKE'[int(body) % 23]\n    return [letter, t[8].upper() == letter]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression [\"12345678z\"]', ['12345678z'], ['Z', True]], ['regression [\"x1234567l\"]', ['x1234567l'], ['L', True]], ['partial-repair [\"y7654321g\"]', ['y7654321g'], ['G', True]], ['control [\"11888450T\"]', ['11888450T'], ['A', False]], ['control [\"15183137S\"]', ['15183137S'], ['D', False]], ['control [\"96436549C\"]', ['96436549C'], ['X', False]], ['control [\"32369867Q\"]', ['32369867Q'], ['N', False]], ['control [\"84574425H\"]', ['84574425H'], ['K', False]]], [['regression [\"12345678z\"]', ['12345678z'], ['Z', True]], ['regression [\"x1234567l\"]', ['x1234567l'], ['L', True]], ['partial-repair [\"y7654321g\"]', ['y7654321g'], ['G', True]], ['control [\"09456394Q\"]', ['09456394Q'], ['J', False]], ['control [\"06580396K\"]', ['06580396K'], ['G', False]], ['control [\"74087956U\"]', ['74087956U'], ['B', False]], ['control [\"08401512F\"]', ['08401512F'], ['A', False]], ['control [\"73708311E\"]', ['73708311E'], ['G', False]]], [['regression [\"12345678z\"]', ['12345678z'], ['Z', True]], ['regression [\"x1234567l\"]', ['x1234567l'], ['L', True]], ['partial-repair [\"y7654321g\"]', ['y7654321g'], ['G', True]], ['control [\"Z8303596E\"]', ['Z8303596E'], ['A', False]], ['control [\"Y9463691F\"]', ['Y9463691F'], ['X', False]], ['control [\"Y6311829O\"]', ['Y6311829O'], ['E', False]], ['control [\"Y1496345D\"]', ['Y1496345D'], ['W', False]], ['control [\"Y4913243Z\"]', ['Y4913243Z'], ['C', False]]], [['regression [\"12345678z\"]', ['12345678z'], ['Z', True]], ['regression [\"x1234567l\"]', ['x1234567l'], ['L', True]], ['partial-repair [\"y7654321g\"]', ['y7654321g'], ['G', True]], ['control [\"Z4573064S\"]', ['Z4573064S'], ['W', False]], ['control [\"Y2667738D\"]', ['Y2667738D'], ['M', False]], ['control [\"X4304629M\"]', ['X4304629M'], ['H', False]], ['control [\"Z8719589B\"]', ['Z8719589B'], ['H', False]], ['control [\"X5964504D\"]', ['X5964504D'], ['Y', False]]], [['regression [\"12345678z\"]', ['12345678z'], ['Z', True]], ['regression [\"x1234567l\"]', ['x1234567l'], ['L', True]], ['partial-repair [\"y7654321g\"]', ['y7654321g'], ['G', True]], ['control [\"12345678Z\"]', ['12345678Z'], ['Z', True]], ['control [\"12345678-Z\"]', ['12345678-Z'], ['Z', True]], ['control [\"X1234567L\"]', ['X1234567L'], ['L', True]], ['control [\"Y1234567X\"]', ['Y1234567X'], ['X', True]], ['control [\"Z1234567R\"]', ['Z1234567R'], ['R', True]]]]\nfor label, args, expected in fixtures[N - 1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"b2cf32b6148042e6be3ac9e52375a0ec92cdad49686d4a2f5e32d718117de20e","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(s):\n    t = s.replace('-', '')\n    if len(t) != 9 or not t.isascii():\n        return 'malformed'\n    body = t[:8]\n    if body[0] in 'XYZ':\n        body = str('XYZ'.index(body[0])) + body[1:]\n    if not body.isdigit() or not t[8].isalpha():\n        return 'malformed'\n    letter = 'TRWAGMYFPDXBNJZSQVHLCKE'[int(body) % 23]\n    return [letter, t[8] == letter]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression [\"12345678z\"]', ['12345678z'], ['Z', True]], ['regression [\"x1234567l\"]', ['x1234567l'], ['L', True]], ['partial-repair [\"y7654321g\"]', ['y7654321g'], ['G', True]], ['control [\"11888450T\"]', ['11888450T'], ['A', False]], ['control [\"15183137S\"]', ['15183137S'], ['D', False]], ['control [\"96436549C\"]', ['96436549C'], ['X', False]], ['control [\"32369867Q\"]', ['32369867Q'], ['N', False]], ['control [\"84574425H\"]', ['84574425H'], ['K', False]]], [['regression [\"12345678z\"]', ['12345678z'], ['Z', True]], ['regression [\"x1234567l\"]', ['x1234567l'], ['L', True]], ['partial-repair [\"y7654321g\"]', ['y7654321g'], ['G', True]], ['control [\"09456394Q\"]', ['09456394Q'], ['J', False]], ['control [\"06580396K\"]', ['06580396K'], ['G', False]], ['control [\"74087956U\"]', ['74087956U'], ['B', False]], ['control [\"08401512F\"]', ['08401512F'], ['A', False]], ['control [\"73708311E\"]', ['73708311E'], ['G', False]]], [['regression [\"12345678z\"]', ['12345678z'], ['Z', True]], ['regression [\"x1234567l\"]', ['x1234567l'], ['L', True]], ['partial-repair [\"y7654321g\"]', ['y7654321g'], ['G', True]], ['control [\"Z8303596E\"]', ['Z8303596E'], ['A', False]], ['control [\"Y9463691F\"]', ['Y9463691F'], ['X', False]], ['control [\"Y6311829O\"]', ['Y6311829O'], ['E', False]], ['control [\"Y1496345D\"]', ['Y1496345D'], ['W', False]], ['control [\"Y4913243Z\"]', ['Y4913243Z'], ['C', False]]], [['regression [\"12345678z\"]', ['12345678z'], ['Z', True]], ['regression [\"x1234567l\"]', ['x1234567l'], ['L', True]], ['partial-repair [\"y7654321g\"]', ['y7654321g'], ['G', True]], ['control [\"Z4573064S\"]', ['Z4573064S'], ['W', False]], ['control [\"Y2667738D\"]', ['Y2667738D'], ['M', False]], ['control [\"X4304629M\"]', ['X4304629M'], ['H', False]], ['control [\"Z8719589B\"]', ['Z8719589B'], ['H', False]], ['control [\"X5964504D\"]', ['X5964504D'], ['Y', False]]], [['regression [\"12345678z\"]', ['12345678z'], ['Z', True]], ['regression [\"x1234567l\"]', ['x1234567l'], ['L', True]], ['partial-repair [\"y7654321g\"]', ['y7654321g'], ['G', True]], ['control [\"12345678Z\"]', ['12345678Z'], ['Z', True]], ['control [\"12345678-Z\"]', ['12345678-Z'], ['Z', True]], ['control [\"X1234567L\"]', ['X1234567L'], ['L', True]], ['control [\"Y1234567X\"]', ['Y1234567X'], ['X', True]], ['control [\"Z1234567R\"]', ['Z1234567R'], ['R', True]]]]\nfor label, args, expected in fixtures[N - 1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"fixed":{"sha256":"f75226d9f3b26f03e18a308654ccc83eba615ce5966e8abeee1fb3dba8b6c45d","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(s):\n    t = s.upper().replace('-', '')\n    if len(t) != 9 or not t.isascii():\n        return 'malformed'\n    body = t[:8]\n    if body[0] in 'XYZ':\n        body = str('XYZ'.index(body[0])) + body[1:]\n    if not body.isdigit() or not t[8].isalpha():\n        return 'malformed'\n    letter = 'TRWAGMYFPDXBNJZSQVHLCKE'[int(body) % 23]\n    return [letter, t[8] == letter]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression [\"12345678z\"]', ['12345678z'], ['Z', True]], ['regression [\"x1234567l\"]', ['x1234567l'], ['L', True]], ['partial-repair [\"y7654321g\"]', ['y7654321g'], ['G', True]], ['control [\"11888450T\"]', ['11888450T'], ['A', False]], ['control [\"15183137S\"]', ['15183137S'], ['D', False]], ['control [\"96436549C\"]', ['96436549C'], ['X', False]], ['control [\"32369867Q\"]', ['32369867Q'], ['N', False]], ['control [\"84574425H\"]', ['84574425H'], ['K', False]]], [['regression [\"12345678z\"]', ['12345678z'], ['Z', True]], ['regression [\"x1234567l\"]', ['x1234567l'], ['L', True]], ['partial-repair [\"y7654321g\"]', ['y7654321g'], ['G', True]], ['control [\"09456394Q\"]', ['09456394Q'], ['J', False]], ['control [\"06580396K\"]', ['06580396K'], ['G', False]], ['control [\"74087956U\"]', ['74087956U'], ['B', False]], ['control [\"08401512F\"]', ['08401512F'], ['A', False]], ['control [\"73708311E\"]', ['73708311E'], ['G', False]]], [['regression [\"12345678z\"]', ['12345678z'], ['Z', True]], ['regression [\"x1234567l\"]', ['x1234567l'], ['L', True]], ['partial-repair [\"y7654321g\"]', ['y7654321g'], ['G', True]], ['control [\"Z8303596E\"]', ['Z8303596E'], ['A', False]], ['control [\"Y9463691F\"]', ['Y9463691F'], ['X', False]], ['control [\"Y6311829O\"]', ['Y6311829O'], ['E', False]], ['control [\"Y1496345D\"]', ['Y1496345D'], ['W', False]], ['control [\"Y4913243Z\"]', ['Y4913243Z'], ['C', False]]], [['regression [\"12345678z\"]', ['12345678z'], ['Z', True]], ['regression [\"x1234567l\"]', ['x1234567l'], ['L', True]], ['partial-repair [\"y7654321g\"]', ['y7654321g'], ['G', True]], ['control [\"Z4573064S\"]', ['Z4573064S'], ['W', False]], ['control [\"Y2667738D\"]', ['Y2667738D'], ['M', False]], ['control [\"X4304629M\"]', ['X4304629M'], ['H', False]], ['control [\"Z8719589B\"]', ['Z8719589B'], ['H', False]], ['control [\"X5964504D\"]', ['X5964504D'], ['Y', False]]], [['regression [\"12345678z\"]', ['12345678z'], ['Z', True]], ['regression [\"x1234567l\"]', ['x1234567l'], ['L', True]], ['partial-repair [\"y7654321g\"]', ['y7654321g'], ['G', True]], ['control [\"12345678Z\"]', ['12345678Z'], ['Z', True]], ['control [\"12345678-Z\"]', ['12345678-Z'], ['Z', True]], ['control [\"X1234567L\"]', ['X1234567L'], ['L', True]], ['control [\"Y1234567X\"]', ['Y1234567X'], ['X', True]], ['control [\"Z1234567R\"]', ['Z1234567R'], ['R', True]]]]\nfor label, args, expected in fixtures[N - 1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"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.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-check_digit_algorithms-es-dni-nie-case-normalization","generated_at":"2026-09-29T14:48:41.959133+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Tax and KYC forms validate the control letter of Spanish national and foreigner identity numbers.","repair":"Upper-case the whole identifier first.","root_cause":"The input is not upper-cased before the prefix and letter checks.","sha256":"a96d974674429036e1d687ba3d8384a6e767414b9ee1229905baaeeeddfb47a3","title":"DNI validation is case-sensitive · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":39.017,"exit_code":1,"observations":[{"actual":["Z",true],"check":"regression [\"12345678z\"]","expected":["Z",true],"passed":true},{"actual":"malformed","check":"regression [\"x1234567l\"]","expected":["L",true],"passed":false},{"actual":"malformed","check":"partial-repair [\"y7654321g\"]","expected":["G",true],"passed":false},{"actual":["A",false],"check":"control [\"11888450T\"]","expected":["A",false],"passed":true},{"actual":["D",false],"check":"control [\"15183137S\"]","expected":["D",false],"passed":true},{"actual":["X",false],"check":"control [\"96436549C\"]","expected":["X",false],"passed":true},{"actual":["N",false],"check":"control [\"32369867Q\"]","expected":["N",false],"passed":true},{"actual":["K",false],"check":"control [\"84574425H\"]","expected":["K",false],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression [\\\"12345678z\\\"]\", \"actual\": [\"Z\", true], \"expected\": [\"Z\", true], \"passed\": true}, {\"check\": \"regression [\\\"x1234567l\\\"]\", \"actual\": \"malformed\", \"expected\": [\"L\", true], \"passed\": false}, {\"check\": \"partial-repair [\\\"y7654321g\\\"]\", \"actual\": \"malformed\", \"expected\": [\"G\", true], \"passed\": false}, {\"check\": \"control [\\\"11888450T\\\"]\", \"actual\": [\"A\", false], \"expected\": [\"A\", false], \"passed\": true}, {\"check\": \"control [\\\"15183137S\\\"]\", \"actual\": [\"D\", false], \"expected\": [\"D\", false], \"passed\": true}, {\"check\": \"control [\\\"96436549C\\\"]\", \"actual\": [\"X\", false], \"expected\": [\"X\", false], \"passed\": true}, {\"check\": \"control [\\\"32369867Q\\\"]\", \"actual\": [\"N\", false], \"expected\": [\"N\", false], \"passed\": true}, {\"check\": \"control [\\\"84574425H\\\"]\", \"actual\": [\"K\", false], \"expected\": [\"K\", false], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":39.003,"exit_code":1,"observations":[{"actual":["Z",false],"check":"regression [\"12345678z\"]","expected":["Z",true],"passed":false},{"actual":"malformed","check":"regression [\"x1234567l\"]","expected":["L",true],"passed":false},{"actual":"malformed","check":"partial-repair [\"y7654321g\"]","expected":["G",true],"passed":false},{"actual":["A",false],"check":"control [\"11888450T\"]","expected":["A",false],"passed":true},{"actual":["D",false],"check":"control [\"15183137S\"]","expected":["D",false],"passed":true},{"actual":["X",false],"check":"control [\"96436549C\"]","expected":["X",false],"passed":true},{"actual":["N",false],"check":"control [\"32369867Q\"]","expected":["N",false],"passed":true},{"actual":["K",false],"check":"control [\"84574425H\"]","expected":["K",false],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression [\\\"12345678z\\\"]\", \"actual\": [\"Z\", false], \"expected\": [\"Z\", true], \"passed\": false}, {\"check\": \"regression [\\\"x1234567l\\\"]\", \"actual\": \"malformed\", \"expected\": [\"L\", true], \"passed\": false}, {\"check\": \"partial-repair [\\\"y7654321g\\\"]\", \"actual\": \"malformed\", \"expected\": [\"G\", true], \"passed\": false}, {\"check\": \"control [\\\"11888450T\\\"]\", \"actual\": [\"A\", false], \"expected\": [\"A\", false], \"passed\": true}, {\"check\": \"control [\\\"15183137S\\\"]\", \"actual\": [\"D\", false], \"expected\": [\"D\", false], \"passed\": true}, {\"check\": \"control [\\\"96436549C\\\"]\", \"actual\": [\"X\", false], \"expected\": [\"X\", false], \"passed\": true}, {\"check\": \"control [\\\"32369867Q\\\"]\", \"actual\": [\"N\", false], \"expected\": [\"N\", false], \"passed\": true}, {\"check\": \"control [\\\"84574425H\\\"]\", \"actual\": [\"K\", false], \"expected\": [\"K\", false], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":39.9,"exit_code":0,"observations":[{"actual":["Z",true],"check":"regression [\"12345678z\"]","expected":["Z",true],"passed":true},{"actual":["L",true],"check":"regression [\"x1234567l\"]","expected":["L",true],"passed":true},{"actual":["G",true],"check":"partial-repair [\"y7654321g\"]","expected":["G",true],"passed":true},{"actual":["A",false],"check":"control [\"11888450T\"]","expected":["A",false],"passed":true},{"actual":["D",false],"check":"control [\"15183137S\"]","expected":["D",false],"passed":true},{"actual":["X",false],"check":"control [\"96436549C\"]","expected":["X",false],"passed":true},{"actual":["N",false],"check":"control [\"32369867Q\"]","expected":["N",false],"passed":true},{"actual":["K",false],"check":"control [\"84574425H\"]","expected":["K",false],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression [\\\"12345678z\\\"]\", \"actual\": [\"Z\", true], \"expected\": [\"Z\", true], \"passed\": true}, {\"check\": \"regression [\\\"x1234567l\\\"]\", \"actual\": [\"L\", true], \"expected\": [\"L\", true], \"passed\": true}, {\"check\": \"partial-repair [\\\"y7654321g\\\"]\", \"actual\": [\"G\", true], \"expected\": [\"G\", true], \"passed\": true}, {\"check\": \"control [\\\"11888450T\\\"]\", \"actual\": [\"A\", false], \"expected\": [\"A\", false], \"passed\": true}, {\"check\": \"control [\\\"15183137S\\\"]\", \"actual\": [\"D\", false], \"expected\": [\"D\", false], \"passed\": true}, {\"check\": \"control [\\\"96436549C\\\"]\", \"actual\": [\"X\", false], \"expected\": [\"X\", false], \"passed\": true}, {\"check\": \"control [\\\"32369867Q\\\"]\", \"actual\": [\"N\", false], \"expected\": [\"N\", false], \"passed\": true}, {\"check\": \"control [\\\"84574425H\\\"]\", \"actual\": [\"K\", false], \"expected\": [\"K\", false], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}