Verifica del codice fiscale

criric

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
21 Ago 2010
5.607
54
48
TN
Ciao a tutti,
questa mattina mi serviva verificare un codice fiscale e trovato in rete un ottimo script : http://www.icosaedro.it/cf-pi/index.html

Dopodichè mi sono messo a cercarne uno per generarli.

Alla fine ho preferito scriverlo.

Ho creato due pagine:

calcolocf.php // contiene il form per l'inserimento dei dati

calcolo_cf_class.php // contiene i metodi per calcolare il codice fiscale

Per funzionare ha bisogno di una tabella mysql che io ho chiamato listacomuni

L'ho generata da un file di testo che potete trovare a questo indirizzo http://lab.comuni-italiani.it/download/comuni.html

Al momento non saprei come farvi avere il file sql che ho creato.

Sicuramente lo script non è perfetto nel senso che alcune eccezioni probabilmente non riuscirà a risolverle, in
più non ho considerato i nati all'estero ma può essere implementato e ottimizzato.

Per ora lo posto così com'è. Può essere un buon punto di partenza. Si accettano consigli e modifiche.

calcolocf.php

PHP:
<?php
//Richiamo il file che contiene la classe
require_once 'calcolo_cf_class.php';

//Creo un'istanza della classe
$cf_calc = new Calcolo_CF();

//Questa variabile conterrà il codice fiscale calcolato o i messaggi per l'utente
$codice_fiscale = "Compila i campi del form";

//Creo un array per i mesi dell'anno
$mesi = array(1, "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre");

//Controllo se è stato inviato il form
if (isset($_POST['calcola'])) {
    //Verifico che nessun post sia vuoto
    $campivuoti = 0;
    foreach ($_POST as $value) {
        if (empty($value)) {
            $campivuoti++;
            $codice_fiscale = "Tutti i campi sono obbligatori";
        }
    }
    //Assegno i valori dei post
    $nome = $_POST['nome'];
    $cognome = $_POST['cognome'];
    $giorno = $_POST['giorno'];
    $mese = $_POST['mese'];
    $anno = $_POST['anno'];
    $nascita = $anno . "-" . $mese . "-" . $giorno;
    $comune = $_POST['comune'];
    $sesso = $_POST['sesso'];

    if ($campivuoti == 0) {
        //Richiamo il metodo
        $codice_fiscale = $cf_calc->calcolacf($nome, $cognome, $nascita, $comune, $sesso);
    }
}
?>
<!-- Un po di css -->
<style type="text/css">
    table td {
        text-align: left;
        text-indent: 5px;
    }
    td.et {
        width:120px;
        text-align: right;
        padding-right:4px;
    }
    td.right {
        text-align: right;
    }
</style>
<!-- Form inserimento dati -->
<table>
    <form action="calcolocf.php" method="post">
        <tr>
            <td class="et">Codice Fiscale : </td>
            <td><b><?php echo $codice_fiscale; ?></b></td>
        </tr>
        <tr><td colspan="2">&nbsp;</td></tr>
        <tr>
            <td class="et">Nome :</td>
            <td><input type ="text" name="nome" value="<?php if (isset($_POST['nome']))
    echo $_POST['nome'] ?>"/></td>
        </tr>
        <tr>
            <td class="et">Cognome : </td>
            <td><input type ="text" name="cognome" value="<?php if (isset($_POST['cognome']))
                       echo $_POST['cognome'] ?>"/></<td>
        </tr>
        <tr>
            <td class="et">Data di nascita: </td>
            <td><select name="giorno">
                    <?php
                    for ($i = 1; $i < 32; $i++) {
                        $i = str_pad($i, 2, '0', STR_PAD_LEFT);
                        echo "<option value='$i'";
                        if (isset($_POST['giorno']) && $_POST['giorno'] == $i) {
                            echo " selected='selected'";
                        }
                        echo ">$i</option>";
                    }
                    ?>
                </select>
                <select name="mese">
                    <?php
                    for ($i = 1; $i < 13; $i++) {

                        echo "<option value='$i'";
                        if (isset($_POST['mese']) && $_POST['mese'] == $i) {
                            echo " selected='selected'";
                        }
                        echo ">$mesi[$i]\n";
                    }
                    ?>
                </select>
                <select name="anno">
                    <?php
                    for ($i = 1900; $i <= date('Y'); $i++) {
                        echo "<option value='$i'";
                        if (isset($_POST['anno']) && $_POST['anno'] == $i || $i == 1970) {
                            echo " selected='selected'";
                        }
                        echo ">$i</option>";
                    }
                    ?>
                </select>
            </td>
        </tr>
        <tr>
            <td class="et">Luogo di nascita: </<td>
            <td>
                <?php
                $conn = mysql_connect('localhost', 'root', '', 'newcriric');
                $db = mysql_select_db('newcriric', $conn);

                /*
                 * La tabella comuni è stata generata da un file di testo presente a questo indirizzo
                 * http://lab.comuni-italiani.it/download/comuni.html
                 * I dati sono separati da ";" (punto e virgola). 
                 * I campi presenti sono: Codice Istat; Nome Comune; Sigla Provincia; Sigla Regione; 
                 * Prefisso Telefonico; CAP; Codice Catastale (codice fisco); Abitanti; Link Pagina Info
                 */

                $query = "SELECT codFisco,comune FROM listacomuni";
                $result = mysql_query($query);

                echo "<select name='comune'>";
                echo "<option value=''></option>";
                while ($row = mysql_fetch_assoc($result)) {
                    echo "<option value='" . $row['codFisco'] . "'";
                    if (isset($_POST['comune']) && $_POST['comune'] == $row['codFisco']) {
                        echo " selected='selected'";
                    }
                    echo ">" . $row['comune'] . "</option>\n";
                }

                echo "</select>";

                mysql_close();
                ?>
            </td>
        </tr>
        <tr>
            <td class="et">Sesso: </td>
            <td><select name="sesso">
                    <option value=""></option>
                    <option value="M"
                    <?php
                    if (isset($_POST['sesso']) && $_POST['sesso'] == "M") {
                        echo " selected='selected'";
                    }
                    ?>
                            >M</option>
                    <option value="F"
                    <?php
                    if (isset($_POST['sesso']) && $_POST['sesso'] == "F") {
                        echo " selected='selected'";
                    }
                    ?>        
                            >F</option>
                </select>
            </td>
        </tr>
        <tr>
            <td class="right" colspan="2"><input type="submit" name="calcola" value="Calcola"/></td>
        </tr>    
    </form>
</table>
Ho dimenticato il titolo
 
Ultima modifica:

criric

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
21 Ago 2010
5.607
54
48
TN
calcolo_cf_class.php

PHP:
<?php

class Calcolo_CF {
    /*
     * Questo metodo è l'unico pubblico 
     * Prende come parametri tutti i dati necessari
     * Restituisce il codice fiscale
     */

    public function calcolacf($nome, $cognome, $nascita, $comune, $sesso) {

        $nome = strtoupper($nome);
        $cognome = strtoupper($cognome);

        $cf_cognome = $this->ret_cf_cognome($cognome);
        $cf_nome = $this->ret_cf_nome($nome);
        $cf_nascita = $this->ret_cf_nascita($nascita, $sesso);
        

        $cf = $cf_cognome . $cf_nome . $cf_nascita . $comune;

        $cf_last = $this->ret_cf_ultimo_carattere($cf);

        $cf = $cf_cognome . $cf_nome . $cf_nascita . $comune . $cf_last;

        return $cf;
    }

    /*
     * Questa funzione l'ho recuperata a questo link : http://www.icosaedro.it/cf-pi/index.html
     * Sono presenti due ottimi script per la verifica del codice fiscale e della partita iva
     * Il metodo restituisce l'ultimo carattere del CF 
     * Prende come parametro il CF privo dell'ultimo carattere
     */

    private function ret_cf_ultimo_carattere($cf) {
        $s = 0;
        for ($i = 1; $i <= 13; $i += 2) {
            $c = $cf[$i];
            if ('0' <= $c && $c <= '9')
                $s += ord($c) - ord('0');
            else
                $s += ord($c) - ord('A');
        }
        for ($i = 0; $i <= 14; $i += 2) {
            $c = $cf[$i];
            switch ($c) {
                case '0': $s += 1;
                    break;
                case '1': $s += 0;
                    break;
                case '2': $s += 5;
                    break;
                case '3': $s += 7;
                    break;
                case '4': $s += 9;
                    break;
                case '5': $s += 13;
                    break;
                case '6': $s += 15;
                    break;
                case '7': $s += 17;
                    break;
                case '8': $s += 19;
                    break;
                case '9': $s += 21;
                    break;
                case 'A': $s += 1;
                    break;
                case 'B': $s += 0;
                    break;
                case 'C': $s += 5;
                    break;
                case 'D': $s += 7;
                    break;
                case 'E': $s += 9;
                    break;
                case 'F': $s += 13;
                    break;
                case 'G': $s += 15;
                    break;
                case 'H': $s += 17;
                    break;
                case 'I': $s += 19;
                    break;
                case 'J': $s += 21;
                    break;
                case 'K': $s += 2;
                    break;
                case 'L': $s += 4;
                    break;
                case 'M': $s += 18;
                    break;
                case 'N': $s += 20;
                    break;
                case 'O': $s += 11;
                    break;
                case 'P': $s += 3;
                    break;
                case 'Q': $s += 6;
                    break;
                case 'R': $s += 8;
                    break;
                case 'S': $s += 12;
                    break;
                case 'T': $s += 14;
                    break;
                case 'U': $s += 16;
                    break;
                case 'V': $s += 10;
                    break;
                case 'W': $s += 22;
                    break;
                case 'X': $s += 25;
                    break;
                case 'Y': $s += 24;
                    break;
                case 'Z': $s += 23;
                    break;
            }
        }
        return chr($s % 26 + ord('A'));
    }

    /*
     * prende come parametri la data di nascita in formato aaaa-mm-gg e il sesso
     * restituisce la data di nascita nel formato del CF
     */

    private function ret_cf_nascita($nascita, $sesso) {
        // validare la data
        $nascita = explode('-', $nascita);

        $mese = $this->ret_cf_mese($nascita[1]);
        $anno = substr($nascita[0], 2);
        $giorno = $nascita[2];

        if ($sesso == "F") {
            $giorno+=40;
        }

        return $anno . $mese . $giorno;
    }

    /*
     * Prende come parametro il numero del mese
     * Restituisce la lettera corrispondente
     */

    private function ret_cf_mese($mese) {
        $mese = (int) $mese;
        $array_mesi = array(1, "A", "B", "C", "D", "E", "H", "L", "M", "P", "R", "S", "T");

        foreach ($array_mesi as $key => $value) {
            if ($key == $mese) {
                return $value;
            }
        }
        return "Valore non trovato";
    }

    /*
     * Prende come parametro il nome
     * Restituisce i 3 caratteri necessari al CF
     */

    private function ret_cf_nome($nome) {

        $consonanti = array();
        for ($i = 0; $i < strlen($nome); $i++) {
            if ($this->is_consonante($nome[$i])) {
                $consonanti[] = $nome[$i];
            }
        }

        switch (count($consonanti)) {
            case 1:
                $prima_vocale = $this->prima_vocale($nome);
                return $consonanti[0] . $prima_vocale . "X";
                break;
            case 2:
                $prima_vocale = $this->prima_vocale($nome);
                return $consonanti[0] . $consonanti[1] . $prima_vocale;
                break;
            case 3:
                return $consonanti[0] . $consonanti[1] . $consonanti[2];
                break;
            default:
                return $consonanti[0] . $consonanti[2] . $consonanti[3];
                break;
        }
    }

    /*
     * Prende come parametro il cognome
     * Restituisce i 3 caratteri necessari al CF
     */

    private function ret_cf_cognome($cognome) {

        $consonanti = array();
        for ($i = 0; $i < strlen($cognome); $i++) {
            if ($this->is_consonante($cognome[$i])) {
                $consonanti[] = $cognome[$i];
            }
        }

        switch (count($consonanti)) {
            case 1:
                $prima_vocale = $this->prima_vocale($cognome);
                return $consonanti[0] . $prima_vocale . "X";
                break;
            case 2:
                $prima_vocale = $this->prima_vocale($cognome);
                return $consonanti[0] . $consonanti[1] . $prima_vocale;
                break;
            default:
                return $consonanti[0] . $consonanti[1] . $consonanti[2];
                break;
        }
    }

    /*
     * Prende come parametro un carattere maiuscolo e verifica se è una vocale
     * Restituisce true se consonante false se vocale
     */

    private function is_consonante($ch) {

        $array_vocali = array('A', 'E', 'I', 'O', 'U');

        foreach ($array_vocali as $value) {
            if ($ch == $value) {
                return false;
            }
        }
        return true;
    }

    /*
     * Prende come parametro una stringa
     * Restituisce la prima vocale
     */

    private function prima_vocale($stringa) {

        $array_vocali = array('A', 'E', 'I', 'O', 'U');

        for ($i = 0; $i < strlen($stringa); $i++) {
            if (in_array($stringa[$i], $array_vocali)) {
                return $stringa[$i];
            }
        }

        return "X";
    }

}

?>
Dimenticavo le istruzioni per il calcolo le ho trovate qui : http://gratis.pietrelcinanet.com/codice_fiscale/codice.htm
 
Ultima modifica:

criric

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
21 Ago 2010
5.607
54
48
TN
Devo subito fare una modifica

Elimino gli spazi e metto un controllino sui post

PHP:
//Verifico che nessun post sia vuoto
    $campivuoti = 0;
    foreach ($_POST as $key => $value) {

       $_POST[$key] = addslashes(preg_replace("%'%", "", str_replace(" ", "", trim($value))));

        if (empty($value)) {
            $campivuoti++;
            $codice_fiscale = "Tutti i campi sono obbligatori";
        }
    }
ok modificato
 
Ultima modifica:

criric

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
21 Ago 2010
5.607
54
48
TN
Ragazzi scusate ma ho dovuto modificare 2 metodi e aggiungerne uno per l'eventuale seconda vocale

Forse ho postato troppo presto

Vi riposto la classe
PHP:
<?php

class Calcolo_CF {
    /*
     * Questo metodo è l'unico pubblico 
     * Prende come parametri tutti i dati necessari
     * Restituisce il codice fiscale
     */

    public function calcolacf($nome, $cognome, $nascita, $comune, $sesso) {

        $nome = strtoupper($nome);
        $cognome = strtoupper($cognome);

        $cf_cognome = $this->ret_cf_cognome($cognome);
        $cf_nome = $this->ret_cf_nome($nome);
        $cf_nascita = $this->ret_cf_nascita($nascita, $sesso);


        $cf = $cf_cognome . $cf_nome . $cf_nascita . $comune;

        $cf_last = $this->ret_cf_ultimo_carattere($cf);

        $cf = $cf_cognome . $cf_nome . $cf_nascita . $comune . $cf_last;

        return $cf;
    }

    /*
     * Questa funzione l'ho recuperata a questo link : http://www.icosaedro.it/cf-pi/index.html
     * Sono presenti due ottimi script per la verifica del codice fiscale e della partita iva
     * Il metodo restituisce l'ultimo carattere del CF 
     * Prende come parametro il CF privo dell'ultimo carattere
     */

    private function ret_cf_ultimo_carattere($cf) {
        $s = 0;
        for ($i = 1; $i <= 13; $i += 2) {
            $c = $cf[$i];
            if ('0' <= $c && $c <= '9')
                $s += ord($c) - ord('0');
            else
                $s += ord($c) - ord('A');
        }
        for ($i = 0; $i <= 14; $i += 2) {
            $c = $cf[$i];
            switch ($c) {
                case '0': $s += 1;
                    break;
                case '1': $s += 0;
                    break;
                case '2': $s += 5;
                    break;
                case '3': $s += 7;
                    break;
                case '4': $s += 9;
                    break;
                case '5': $s += 13;
                    break;
                case '6': $s += 15;
                    break;
                case '7': $s += 17;
                    break;
                case '8': $s += 19;
                    break;
                case '9': $s += 21;
                    break;
                case 'A': $s += 1;
                    break;
                case 'B': $s += 0;
                    break;
                case 'C': $s += 5;
                    break;
                case 'D': $s += 7;
                    break;
                case 'E': $s += 9;
                    break;
                case 'F': $s += 13;
                    break;
                case 'G': $s += 15;
                    break;
                case 'H': $s += 17;
                    break;
                case 'I': $s += 19;
                    break;
                case 'J': $s += 21;
                    break;
                case 'K': $s += 2;
                    break;
                case 'L': $s += 4;
                    break;
                case 'M': $s += 18;
                    break;
                case 'N': $s += 20;
                    break;
                case 'O': $s += 11;
                    break;
                case 'P': $s += 3;
                    break;
                case 'Q': $s += 6;
                    break;
                case 'R': $s += 8;
                    break;
                case 'S': $s += 12;
                    break;
                case 'T': $s += 14;
                    break;
                case 'U': $s += 16;
                    break;
                case 'V': $s += 10;
                    break;
                case 'W': $s += 22;
                    break;
                case 'X': $s += 25;
                    break;
                case 'Y': $s += 24;
                    break;
                case 'Z': $s += 23;
                    break;
            }
        }
        return chr($s % 26 + ord('A'));
    }

    /*
     * prende come parametri la data di nascita in formato aaaa-mm-gg e il sesso
     * restituisce la data di nascita nel formato del CF
     */

    private function ret_cf_nascita($nascita, $sesso) {
        // validare la data
        $nascita = explode('-', $nascita);

        $mese = $this->ret_cf_mese($nascita[1]);
        $anno = substr($nascita[0], 2);
        $giorno = $nascita[2];

        if ($sesso == "F") {
            $giorno+=40;
        }

        return $anno . $mese . $giorno;
    }

    /*
     * Prende come parametro il numero del mese
     * Restituisce la lettera corrispondente
     */

    private function ret_cf_mese($mese) {
        $mese = (int) $mese;
        $array_mesi = array(1, "A", "B", "C", "D", "E", "H", "L", "M", "P", "R", "S", "T");

        foreach ($array_mesi as $key => $value) {
            if ($key == $mese) {
                return $value;
            }
        }
        return "Valore non trovato";
    }

    /*
     * Prende come parametro il nome
     * Restituisce i 3 caratteri necessari al CF
     */

    private function ret_cf_nome($nome) {

        $consonanti = array();
        for ($i = 0; $i < strlen($nome); $i++) {
            if ($this->is_consonante($nome[$i])) {
                $consonanti[] = $nome[$i];
            }
        }

        switch (count($consonanti)) {
            // modificato
            case 0:
                $prima_vocale = $this->prima_vocale($nome);
                $seconda_vocale = $this->seconda_vocale($nome);
                return $prima_vocale . $seconda_vocale . "X";
                break;
            case 1:
                $prima_vocale = $this->prima_vocale($nome);
                $seconda_vocale = $this->seconda_vocale($nome);
                return $consonanti[0] . $prima_vocale . $seconda_vocale;
                break;
            case 2:
                $prima_vocale = $this->prima_vocale($nome);
                return $consonanti[0] . $consonanti[1] . $prima_vocale;
                break;
            case 3:
                return $consonanti[0] . $consonanti[1] . $consonanti[2];
                break;
            default:
                return $consonanti[0] . $consonanti[2] . $consonanti[3];
                break;
        }
    }

    /*
     * Prende come parametro il cognome
     * Restituisce i 3 caratteri necessari al CF
     */

    private function ret_cf_cognome($cognome) {

        $consonanti = array();
        for ($i = 0; $i < strlen($cognome); $i++) {
            if ($this->is_consonante($cognome[$i])) {
                $consonanti[] = $cognome[$i];
            }
        }

        switch (count($consonanti)) {
            //modificato
            case 0:
                $prima_vocale = $this->prima_vocale($cognome);
                $seconda_vocale = $this->seconda_vocale($cognome);
                return $prima_vocale . $seconda_vocale . "X";
                break;
            case 1:
                $prima_vocale = $this->prima_vocale($cognome);
                $seconda_vocale = $this->seconda_vocale($cognome);
                return $consonanti[0] . $prima_vocale . $seconda_vocale;
                break;
            case 2:
                $prima_vocale = $this->prima_vocale($cognome);
                return $consonanti[0] . $consonanti[1] . $prima_vocale;
                break;
            default:
                return $consonanti[0] . $consonanti[1] . $consonanti[2];
                break;
        }
    }

    /*
     * Prende come parametro un carattere maiuscolo e verifica se è una vocale
     * Restituisce true se consonante false se vocale
     */

    private function is_consonante($ch) {

        $array_vocali = array('A', 'E', 'I', 'O', 'U');

        foreach ($array_vocali as $value) {
            if ($ch == $value) {
                return false;
            }
        }
        return true;
    }

    /*
     * Prende come parametro una stringa
     * Restituisce la prima vocale
     */

    private function prima_vocale($stringa) {

        $array_vocali = array('A', 'E', 'I', 'O', 'U');

        for ($i = 0; $i < strlen($stringa); $i++) {
            if (in_array($stringa[$i], $array_vocali)) {
                return $stringa[$i];
            }
        }

        return "X";
    }

    private function seconda_vocale($stringa) {

        $array_vocali = array('A', 'E', 'I', 'O', 'U');

        $vocali = array();
        for ($i = 0; $i < strlen($stringa); $i++) {
            if (in_array($stringa[$i], $array_vocali)) {
                $vocali[] = $stringa[$i];
            }
        }
        if (count($vocali) >= 2) {
            return $vocali[1];
        }
        return "X";
    }

}

?>
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.041
146
63
PR
www.borgo-italia.it
ciao
secondo me c'è un errore qui, ciclando l'array $_POST, se hai dato l'invio in $_POST['calcola'] c'è un valore
io metterei:
PHP:
<?php
//....
//Controllo se è stato inviato il form
if (isset($_POST['calcola'])) {
    //Verifico che nessun post sia vuoto
    unset($_POST['calcola']);//elimino l'elemento 'calcola'
	$campivuoti = 0;
    foreach ($_POST as $value) {
        if (empty($value)) {
            $campivuoti++;
            $codice_fiscale = "Tutti i campi sono obbligatori";
        }
    }
//...
?>
 

criric

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
21 Ago 2010
5.607
54
48
TN
Si,
$_POST['calcola'] contiene la stringa "Calcola"

ma il ciclo verifica che nessun $_POST sia vuoto quindi non crea problemi quel POST

certo eviterei di trimmarlo e verificarlo per niente

Potrebbe esserre un buon risparmio di microsecondi

grazie
 

jan267

Utente Attivo
6 Mar 2003
1.956
2
38
31
Milano
twitter.com
Ciao a tutti,
dopo anni che non scrivo ricevo una mail di notifica di aggiornamento del post.
Leggo e vedo che si tratta di una classe per creare il codice fiscale.
Ci tenevo dunque a segnalare una mia classe ospitata presso PEAR per validare un codice fiscale e altre "robe"!

http://pear.php.net/package/Validate_IT

Spero possa essere utile a qualuno e che qualcuno abbia anche voglia e tempo scrivere nuovi metodi e migliorare quelli esistenti!

Buona giornata :)
J.
 

criric

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
21 Ago 2010
5.607
54
48
TN
Meglio tardi che mai :dormo:
mi hanno fatto notare che il metodo sigla_nome() è sbagliato. In realtà come spiegato ache nei link citati nella classe le consonanti utilizzate per il codice fiscale sono la prima, la terza e la quarta sempre che nel nome ne siano presenti almeno 4.
Lo script restituiva sempre la prima la seconda e la terza.
Ecco la modifica.
PHP:
    private function sigla_nome($nome) {

        $consonanti = array();
        for ($i = $c = 0; $i < strlen($nome); $i++) {
            if (!in_array($nome[$i], array('A', 'E', 'I', 'O', 'U'))) {
                $consonanti[] = $nome[$i];
                $c++;
            }
        }
        $n = count($consonanti);
        if ($n > 3) {
            unset($consonanti[1]);
        }
        if ($n < 3) {
            for ($x = 0; $x < 3 - $n; $x++) {
                $consonanti[] = $this->prendi_vocale($x, $nome);
            }
        }
        return implode("", array_slice($consonanti, 0, 3));
    }