Vai al contenuto
Calcolo Codice Fiscale Inverso

API codice fiscale

Non esiste un’API pubblica ufficiale del codice fiscale. Esiste un servizio web dell’Agenzia delle Entrate, fatto per essere usato da una persona con un browser. Per un software la risposta non è cercare un endpoint che non c’è, ma capire quale metà del problema si risolve in locale, che è la metà che conta.

Esiste un’API ufficiale?

No, e vale la pena dirlo chiaramente perché la ricerca «api codice fiscale» porta spesso a servizi di terze parti presentati come se fossero istituzionali. Il servizio pubblico di controllo del codice fiscale in Agenzia delle Entrate è una interfaccia per persone: confronta un codice con dati anagrafici che qualcuno digita, e restituisce una corrispondenza.

Il confine fra i due controlli

Prima di scrivere codice conviene sapere a quali domande si può rispondere.

DomandaDove si rispondeCosto
Il codice è ben formato?nel tuo codice, in localenessuno
Il carattere di controllo torna?nel tuo codice, in localenessuno
La persona esiste in Anagrafe tributaria?solo il servizio dell’Agenzia delle Entrateinterazione umana, nessun endpoint pubblico
A chi appartiene il codice?nessuno, per progettonon è una domanda a cui si possa rispondere

Le prime due righe coprono quasi tutti i casi d’uso reali di un form o di una importazione, e non richiedono rete.

Validazione in PHP

Una classe autosufficiente, senza dipendenze e senza chiamate di rete. Le altre lingue hanno la loro pagina: JavaScript, Python e la regex di validazione.

<?php
declare(strict_types=1);

/**
 * Validazione formale del codice fiscale.
 * Nessuna dipendenza, nessuna chiamata di rete: tutto ciò che serve
 * per il carattere di controllo sta nelle due tabelle qui sotto.
 */
final class CodiceFiscale
{
    /** Valori delle posizioni dispari, contate a partire da 1. */
    private const DISPARI = [
        '0' => 1,  '1' => 0,  '2' => 5,  '3' => 7,  '4' => 9,
        '5' => 13, '6' => 15, '7' => 17, '8' => 19, '9' => 21,
        'A' => 1,  'B' => 0,  'C' => 5,  'D' => 7,  'E' => 9,
        'F' => 13, 'G' => 15, 'H' => 17, 'I' => 19, 'J' => 21,
        'K' => 2,  'L' => 4,  'M' => 18, 'N' => 20, 'O' => 11,
        'P' => 3,  'Q' => 6,  'R' => 8,  'S' => 12, 'T' => 14,
        'U' => 16, 'V' => 10, 'W' => 22, 'X' => 25, 'Y' => 24,
        'Z' => 23,
    ];

    /** Valori delle posizioni pari: cifra per le cifre, indice alfabetico per le lettere. */
    private const PARI = [
        '0' => 0,  '1' => 1,  '2' => 2,  '3' => 3,  '4' => 4,
        '5' => 5,  '6' => 6,  '7' => 7,  '8' => 8,  '9' => 9,
        'A' => 0,  'B' => 1,  'C' => 2,  'D' => 3,  'E' => 4,
        'F' => 5,  'G' => 6,  'H' => 7,  'I' => 8,  'J' => 9,
        'K' => 10, 'L' => 11, 'M' => 12, 'N' => 13, 'O' => 14,
        'P' => 15, 'Q' => 16, 'R' => 17, 'S' => 18, 'T' => 19,
        'U' => 20, 'V' => 21, 'W' => 22, 'X' => 23, 'Y' => 24,
        'Z' => 25,
    ];

    public static function normalizza(string $cf): string
    {
        return strtoupper(preg_replace('/\s+/', '', $cf) ?? '');
    }

    /**
     * Forma attesa, omocodia compresa: nelle posizioni numeriche le cifre
     * possono essere sostituite dalle lettere L, M, N, P, Q, R, S, T, U, V.
     */
    public static function formaValida(string $cf): bool
    {
        $re = '/^[A-Z]{6}'          // cognome e nome
            . '[0-9LMNPQRSTUV]{2}'  // anno
            . '[ABCDEHLMPRST]'      // mese
            . '[0-9LMNPQRSTUV]{2}'  // giorno, con il 40 per il sesso femminile
            . '[A-Z]'               // prima lettera del codice catastale
            . '[0-9LMNPQRSTUV]{3}'  // resto del codice catastale
            . '[A-Z]$/';            // carattere di controllo
        return (bool) preg_match($re, $cf);
    }

    /** Il sedicesimo carattere, calcolato sui quindici precedenti. */
    public static function carattereDiControllo(string $primi15): string
    {
        $somma = 0;
        for ($i = 0; $i < 15; $i++) {
            $c = $primi15[$i];
            // Indice 0 in base 0 e' la prima posizione in base 1, quindi dispari.
            $somma += ($i % 2 === 0) ? self::DISPARI[$c] : self::PARI[$c];
        }
        return chr(ord('A') + ($somma % 26));
    }

    public static function valido(string $cf): bool
    {
        $cf = self::normalizza($cf);
        if (!self::formaValida($cf)) {
            return false;
        }
        return self::carattereDiControllo(substr($cf, 0, 15)) === $cf[15];
    }
}

L’uso, e i limiti:

// Il carattere di controllo intercetta la trascrizione sbagliata,
// non l'esistenza della persona.
var_dump(CodiceFiscale::valido('RSSMRA85T10A562S')); // bool(true)
var_dump(CodiceFiscale::valido('RSSMRA85T10A562A')); // bool(false), controllo errato
var_dump(CodiceFiscale::valido('RSSMRA85T10A562'));  // bool(false), quindici caratteri

Se ti serve un endpoint interno

Incapsulare la validazione dietro un servizio interno è ragionevole quando più applicazioni devono condividere la stessa regola. Due accortezze. La prima: non registrare i codici ricevuti, perché sono dati personali e un log di validazione diventa in fretta un archivio che nessuno aveva deciso di creare. La seconda: restituire il motivo del rifiuto, distinguendo la forma sbagliata dal carattere di controllo errato, perché sono errori diversi e portano a correzioni diverse.

I dati di test

I codici delle persone vere non vanno in una suite di test. Servono codici sintetici, formalmente validi e riferiti a nessuno, che si ottengono dal generatore per test e sviluppo oppure dalla pagina sul codice fiscale di prova.

Domande frequenti

Le implementazioni nelle singole lingue stanno nella sezione per chi sviluppa. La forma attesa in una sola espressione è nella regex di validazione. I dati sintetici per la suite di test si ottengono dal generatore per test e sviluppo.

Approfondisci

Avvertenza

Questo strumento decodifica la struttura formale di un codice fiscale e ne verifica il carattere di controllo. Non conferma che il codice sia stato effettivamente attribuito a una persona: quella verifica è possibile solo attraverso il servizio ufficiale dell’Agenzia delle Entrate.