La validazione del codice fiscale

Il codice fiscale è un codice alfanumerico di 16 caratteri, serve a identificare in modo univoco a fini fiscali le persone fisiche residenti sul territorio italiano, prima che venisse inglobato nella tessera sanitaria era consegnato su una tessera plastificata con tanto di banda magnetica. Sulla parte anteriore della tessera sono riportati – oltre al codice stesso – nome, cognome, luogo e data di nascita, sesso e provincia. I 16 caratteri all’interno del codice sono così divisi:

Spesso, in particolare se ci troviamo a dover programmare form di registrazione, ci troveremo prima o poi a doverne controllare la correttezza. Sebbene in pochi lo sanno, il codice fiscale, ha un algoritmo (intrinseco) di verifica della correttezza abbastanza robusto. In questo articolo vedremo concettualmente come funziona questo algoritmo di controllo e come implementarlo in un linguaggio di programmazione. Verrà utilizzato Java per la scrittura dell’algoritmo ma non dovrebbe essere complicato emularlo in altri linguaggi, se avete realizzato una versione in un linguaggio di programmazione diverso da Java potete postarlo tra i commenti e lo inserirò nell’articolo.

Il concetto

Supponendo che ci sia stato inviato un codice fiscale, il nostro algoritmo dovrà controllarne la correttezza sintattica, (ovvero che non ci siano numeri nelle posizioni che dovrebbero essere occupate da lettere) e semantica (ovvero che il carattere di controllo risulti “solidale” rispetto agli altri 15). Per controllare la correttezza sintattica del codice fiscale passato useremo le espressioni regolari, mentre per la correttezza semantica costruiremo un algoritmo apposito per calcolare il sedicesimo carattere sfruttando i 15 forniti. L’esito del confronto tra il carattere di controllo inviato e quello calcolato rileverà la correttezza o meno del codice.

L’algoritmo

La correttezza semantica del codice fiscale, come abbiamo già detto, si basa sulla presenza del sedicesimo carattere di controllo, ricavato attraverso una serie di operazioni X sui 15 caratteri precedenti. Se il sedicesimo carattere inserito dall’utente è diverso da quello risultante dalle operazioni X allora il codice è semanticamente non corretto. In cosa consistono queste operazioni? Si converte ognuno dei 15 caratteri del codice in un valore numerico rispettando due distinte tabelle di conversione a seconda che stiamo convertendo un carattere pari o un carattere dispari. Ecco le tabelle di conversione:

 

CARATTERI ALFANUMERICI DISPARI
Carattere Valore Carattere Valore Carattere Valore Carattere Valore
0 1 9 21 I 19 R 8
1 0 A 1 J 21 S 12
2 5 B 0 K 2 T 14
3 7 C 5 L 4 U 16
4 9 D 7 M 18 V 10
5 13 E 9 N 20 W 22
6 15 F 13 O 11 X 25
7 17 G 15 P 3 Y 24
8 19 H 17 Q 6 Z 23

 

CARATTERI ALFANUMERICI PARI
Carattere Valore Carattere Valore Carattere Valore Carattere Valore
0 0 9 9 I 8 R 17
1 1 A 0 J 9 S 18
2 2 B 1 K 10 T 19
3 3 C 2 L 11 U 20
4 4 D 3 M 12 V 21
5 5 E 4 N 13 W 22
6 6 F 5 O 14 X 23
7 7 G 6 P 15 Y 24
8 8 H 7 Q 16 Z 25

 

Una volta completata la fase precedente avremo 15 numeri, li sommeremo tra loro e il risultato ottenuto lo divideremo per 26. Il resto di tale divisione restituirà ovviamente un numero intero che dovrà essere trasformato in un carattere alfabetico grazie ad un ulteriore tabella di trasformazione. La tabella è in realtà la tabella dei numeri pari, priva dei caratteri numerici e con i soli caratteri alfabetici.

 

RESTO
Resto Lettera Resto Lettera Resto Lettera Resto Lettera
0 A 7 H 14 O 21 V
1 B 8 I 15 P 22 W
2 C 9 J 16 Q 23 X
3 D 10 K 17 R 24 Y
4 E 11 L 18 S 25 Z
5 F 12 M 19 T
6 G 13 N 20 U

Se il carattere ricavato coincide col sedicesimo carattere fornito dall’utente il codice risulterà semanticamente corretto.

L’algoritmo in Java

package validatorecodicefiscale;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

public class ValidatoreCodiceFiscale {
    public void validaCF(String cf) throws CFException{
       /* espr. regolare per controllare la correttezza sintattica del CF */
       String regex = "[a-zA-Z]{6}[0-9]{2}[a-zA-Z][0-9]{2}[a-zA-Z][0-9]{3}[a-zA-Z]";
       int somma = 0;

       /* Creazione dell'HashMap che realizza l'associazione chiave valore per
       i caratteri dispari */
       Map chrDispari = new HashMap();
       chrDispari.put("0", "1");
       chrDispari.put("1", "0");
       // ...
       chrDispari.put("Y", "24");
       chrDispari.put("Z", "23");

       /* HashMap che realizza l'associazione chiave-valore per i caratteri
        pari all'interno del codice fiscale. */
       Map chrPari = new HashMap();
       chrPari.put("0", "0");
       chrPari.put("1", "1");
       // ...
       chrPari.put("Y", "24");
       chrPari.put("Z", "25");

       /* HashMap che associa un valore numerico per ogni carattere che potrebbe
        essere presente come ultimo carattere del codice fiscale */
       Map chrControllo = new HashMap();
       chrControllo.put("0", "A");
       chrControllo.put("1", "B");
       // ...
       chrControllo.put("24", "Y");
       chrControllo.put("25", "Z");

       /* Effettua la somma di tutti i valori ricavati da ogni singolo carattere
        del CF. Se il carattere è pari, il valore è prelevato dall'HashMap dei
        numeri pari, dispari altrimenti. */
       for(int i=0; i<15; i++) {
           if (i % 2 == 1)
               {
                    somma += Integer.parseInt((String)
                            chrPari.get(Character.toString(cf.charAt(i))));
               }
           else
               {
                    somma += Integer.parseInt((String)
                            chrDispari.get(Character.toString(cf.charAt(i))));
               }
       }

       /* Calcolo l'esatto carattere di controllo in base al codice fiscale
        fornito dall'utente */
       String strControlloCalcolato = (String)chrControllo.get(""+somma%26);
       Character chrControlloCalcolato = strControlloCalcolato.charAt(0);

       /* Ricavo il carattere di controllo fornito dall'utente */
       Character chrControlloInserito = cf.charAt(15);

       if (!Pattern.matches(regex, cf) ||
           !chrControlloInserito.equals(chrControlloCalcolato)
          )
                throw new CFException();
    }
}

Le tre HashMap sono state accorciate nel listato sopra per ovvi motivi di spazio, ma seguendo le giuste tabelle non sarà un problema ricrearle. Nel caso in cui il codice passato dall’utente sarà errato l’algoritmo solleverà un’eccezione definita come segue:

package validatorecodicefiscale;

public class CFException extends Exception {

    public CFException() {
        super("Errore: Il Codice Fiscale inseirto non è valido.");
    }
}

La definizione dell’eccezione è volutamente semplice, in quanto il nostro scopo era quello di comprendere come poter controllare la validità del codice fiscale, non ci perderemo dunque in argomenti collaterali. Per chiunque volesse approfondire la conoscenza delle eccezioni consiglio di leggere questo link: http://www.claudiodesio.com/java/excs.htm. Una volta che abbiamo scritto l’algoritmo di controllo e definito l’eccezione che l’algoritmo potrebbe sollevare, l’unica cosa che ci resta da fare è implementarlo.

ValidatoreCodiceFiscale v = new ValidatoreCodiceFiscale();
        try {
            v.validaCF("CODICEFISCALE");
        } catch (CFException ex) {
            System.out.println("Errore di sintassi e/o di semantica.");
        }

If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.

Comments

Non c’è ancora nessun commento.

Lascia un commento

(obbligatorio)

(obbligatorio)


*
To prove that you're not a bot, enter this code
Anti-Spam Image