#!/usr/bin/perl
#
#   AlberT-CodFis: calcola il codice fiscale.
#   Copyright (C) 2000  Emiliano 'AlberT' Gabrielli &gtAlberT@SuperAlberT.it<
#
#               LA VERSIONE PERL DI QUESTO SCRIPT E' OPERA DI
#                      Paolo Furieri  <furieri@ntc.it>
#
#       THE AUTHOR IS ==NOT== RESPONSIBLE FOR ANY USE OF THIS PROGRAM!
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
#
#   $ AlberT-CodFis.pl v. 1.5  - 14/01/2001
#
                


$CFconf["thisdir"]       =       $DOCUMENT_ROOT."/";  
print &calcolacf("Zizzi","zozzo","01031975","m","arezzo") . "\n"; 
 
sub checkdate() { 
$mm = shift; 
$gg = shift; 
$aa = shift; 
if ($aa < 1900 || $aa > 2010 || $gg < 1 || $gg > 31 || $mm < 1 || $mm > 12) { return 0; } 
if ( ($mm == 4 || $mm == 6 || $mm == 9 || $mm == 11) && $gg > 30) { return 0; }; 
if ( $mm == 2 && $aa % 4 != 0 && $gg > 28) { return 0; } 
if ( $mm == 2 && $gg > 29) { return 0; } 
return 1; 
} 
 
sub toupper() { 
$temp = shift; 
$temp =~ tr/a-z/A-Z/; 
return $temp; 
} 
 
sub levaconsonanti() { 
$temp = shift; 
$temp =~ s/ //g; 
$temp =~ s/[bcdfghjklmnpqrtvwzyzBCDFGHJKLMNPQRSTVWXYZ]//g; 
return $temp; 
} 
 
sub levavocali(){ 
$temp = shift; 
$temp=~ s/ //g; 
$temp=~ s/[aeiouAEIOU]//g; 
return $temp; 
} 
 
sub levastranezze(){ 
$stringa = shift; 
$stringa=~ s/' / /g; 
$stringa=~ s/'/ /g; 
$stringa=~ s/à/a/g; 
$stringa=~ s/è/e/g; 
$stringa=~ s/é/e/g; 
$stringa=~ s/ì/i/g; 
$stringa=~ s/ò/o/g; 
$stringa=~ s/ù/u/g; 
$stringa=~ s/-//g;
$stringa=~ s/\[//g; 
$stringa=~ s/\]//g; 
$stringa=~ s/[\/\\"!?^$|£%&)(=`,;:.+*<>@#°§ç]//g; 
$stringa=~ s/^  *//; 
$stringa=~ s/  *$//; 
return $stringa; 
} 
 
sub sceglifile(){ 
$comune = shift; 
$comune = &toupper($comune); 
$iniziale=substr($comune,0,1); 
if ( $iniziale =~ m/[ABCDE]/ ) { 
$suffisso="1"; 
} 
elsif ( $iniziale =~ m/[FGHIJKLMNOPQR]/ ) { 
$suffisso="2"; 
}             
elsif ( $iniziale =~ m/[STUVWXYZ]/ ) { 
$suffisso="3"; 
}             
else{  
$error = "ERRORE!!! \nERRORE: il comune DEVE iniziare con una lettera!!"; 
return $error; 
} 
$file="comuni_$suffisso.dat"; 
return $file; 
} 
 
sub cercacitta(){ 
$comune = shift; 
if ($comune eq "") { 
$error = "ERRORE: SPECIFICARE UN COMUNE!"; 
return $error; 
} 
$error="Errore!!!\n Non è stato possibile trovare il Comune. Verificare i dati."; 
$comune = substr($comune,0,20); 
$comune = &toupper($comune); 
$f = &sceglifile($comune); 
open INPUT, $f; 
while(<INPUT>) { 
chomp $_; 
@daticitta = split /:/, $_, 3 ;
$daticitta[0] =~ s/ //g;
$comune =~ s/ //g; 

if ($daticitta[0] eq $comune) { 
 $PIPPO="PiPpO"; 
goto FATTO; 
} 
} 
FATTO: 
if ($PIPPO ne "PiPpO")  { $daticitta[0] = ""; $daticitta[1] = $error; } 
return @daticitta; 
} 
 
sub controlladati() { 
$cognome = shift; 
$nome = shift; 
$datadinascita = shift; 
$sesso = shift; 
$citta = shift; 
if ( (length($datadinascita)!=8) || ($datadinascita<=0)) { 
$error="Errore nella data di nascita, la data deve essere nella forma ggmmaaaa"; 
return $error; 
} 
$giorno = substr($datadinascita,0,2); 
$mese   = substr($datadinascita,2,2); 
$anno   = substr($datadinascita,4,4); 
$error  ="Errore nella data di nascita, la data non risulta valida!"; 
if (! &checkdate($mese, $giorno, $anno)) { return $error ; } 
$sesso=&toupper($sesso); 
if (($sesso ne "M") && ($sesso ne "F")) { 
$error = "Errore !!!  Errore nel campo 'sesso' (M/F)" ; 
return $error; 
} 
if ($citta eq "") { 
$error = "Errore !!!\nErrore, specificare il comune di nascita." ; 
return $error; 
} 
else { 
@daticitta=&cercacitta($citta); 
if ($daticitta[0] eq "") { return $daticitta[1]; } 
$sigla  = $daticitta[1]; 
$cod_comune = $daticitta[2]; 
} 
if ( (length($cognome) == 0 ) ) { 
$error = "Errore !!!\nErrore sul campo Cognome, dato non valido."; 
return $error; 
} 
if ( (length($nome) == 0 ) ) { 
$error = "Errore !!!\nErrore sul campo Nome, dato non valido."; 
return $error; 
} 
return $daticitta; 
} 
 
sub calcolacf($cognome, $nome, $datadinascita, $sesso, $citta) { 
$cognome = shift; 
$nome = shift; 
$datadinascita = shift; 
$sesso = shift; 
$citta = shift; 
 
$nome=&levastranezze($nome); 
$cognome=&levastranezze($cognome); 
$citta=&levastranezze($citta); 
 
$cod_comune=""; 
$numvocali=0; 
$numconsonanti=0; 
$numeri="0123456789"; 
$alfabeto    =    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
$alfabeto_dispari="BAKPLCQDREVOSFTGUHMINJWZYX"; 
 
$daticitta= &controlladati($cognome, $nome, $datadinascita, $sesso, $citta); 
if ($daticitta[0] eq "") { return $daticitta; } 
$sigla=$daticitta[1]; 
$cod_comune=$daticitta[2]; 
 
$ooe = &levaconsonanti(&toupper($cognome)); 
$cgnm = &levavocali(&toupper($cognome)); 
 
$numvocali=length($ooe); 
$numconsonanti=length($cgnm); 
 
if ($numconsonanti == 0) { 
if ($numvocali==2){ 
$codicefiscale=$ooe."X"; 
} 
else { 
$error ="Errore !!! \nErrore sul cognome, caso non previsto da questo algoritmo \n...impossibile calcolare il codice fiscale."; 
return $error; 
} 
} 
 
if ($numconsonanti == 1) { 
if ($numvocali == 0) { 
$error ="Errore !!! \nErrore sul cognome, caso non previsto da questo algoritmo \n...impossibile calcolare il codice fiscale."; 
return $error; 
} 
if ($numvocali == 1) { 
$codicefiscale=$cgnm.$ooe."X"; 
} else { 
$codicefiscale=$cgnm . substr($ooe,0,2); 
} 
} 
 
if ($numconsonanti == 2) { 
if ($numvocali>=1) { 
$codicefiscale=$cgnm . substr($ooe,0,1); 
} 
else { 
$error = "Errore !!! \nErrore sul cognome, caso non previsto da questo algoritmo \n...impossibile calcolare il codice fiscale"; 
return $error; 
} 
} 
 
if ($numconsonanti > 2) { 
$codicefiscale=substr($cgnm,0,3); 
} 
 
#  Ora calcolo il nome 
 
$oe = &levaconsonanti(&toupper($nome)); 
$nm = &levavocali(&toupper($nome)); 
$numvocali = length($oe); 
$numconsonanti = length($nm); 
 
if ($numconsonanti == 0) { 
if ($numvocali==2) { 
$codicefiscale.=$oe."X"; 
} 
else { 
$error =  "Errore !!! \nErrore sul nome, caso non previsto da questo algoritmo \n...impossibile calcolare il codice fiscale"; 
return $error; 
} 
} 
 
if ($numconsonanti == 1) { 
if ($numvocali == 0) { 
$error = "Errore !!! \nErrore sul nome, caso non previsto da questo algoritmo \n...impossibile calcolare il codice fiscale"; 
return $error; 
} 
 
if ($numvocali == 1) { 
$codicefiscale.=$nm.substr($oe,0,1)."X"; 
} else { 
$codicefiscale.=$nm.substr($oe,0,2); 
} 
} 
 
if ($numconsonanti == 2) { 
if ($numvocali>=1) { 
$codicefiscale.=substr($nm,0,2).substr($oe,0,1); 
} 
else { 
$error = "Errore !!! \nErrore sul nome, caso non previsto da questo algoritmo \n...impossibile calcolare il codice fiscale"; 
return $error; 
} 
} 
 
if ($numconsonanti == 3) { 
$codicefiscale.=$nm; 
} 
 
if ($numconsonanti > 3) { 
$codicefiscale.=substr($nm,0,1).substr($nm,2,2); 
} 
 
$codicefiscale .= substr($datadinascita,-2); 
 
$mese = substr($datadinascita,2,2); 
 
$lettmese = " ABCDEHLMPRST"; 
$codicefiscale .= substr($lettmese,$mese,1); 
 
$giorno=substr($datadinascita,0,2); 
 
$sesso=&toupper($sesso); 
if ($sesso eq 'M')    { 
$codicefiscale.=substr($datadinascita,0,2); 
} 
else { 
$giorno+=40; 
$codicefiscale.=substr($numeri, $giorno/10, 1); 
$codicefiscale.=substr($numeri, $giorno%10, 1); 
} 
 
$codicefiscale.= $cod_comune; 
 
$numero=0; 
for ($i=0; $i<=14; $i+=2) { # ciclo per i caratteri dispari 
if (substr($codicefiscale,$i,1) ge 'A' && substr($codicefiscale,$i,1) le 'Z') { 
for ($j=0; $j<=26; $j++) { 
if ( substr($codicefiscale,$i,1) eq substr($alfabeto_dispari,$j,1) ) { 
$numero += $j; 
break; 
} 
} 
} 
else {  
$a = substr($codicefiscale,$i,1); 
if ($a eq '0') { $numero+=1; } 
if ($a eq '1') { $numero = $numero; } 
if ($a eq '2') { $numero+=5; } 
if ($a eq '3') { $numero+=7; } 
if ($a eq '4') { $numero+=9; } 
if ($a eq '5') { $numero+=13;} 
if ($a eq '6') { $numero+=15;} 
if ($a eq '7') { $numero+=17;} 
if ($a eq '8') { $numero+=19;} 
if ($a eq '9') { $numero+=21;} 
} 
} 
for ($i=1;$i<=13;$i+=2)  { # ciclo per i caratteri pari 
if (substr($codicefiscale,$i,1) ge 'A' && substr($codicefiscale,$i,1) le 'Z') { 
for ($j=0;$j<=26;$j++) { 
if ( substr($codicefiscale,$i,1) eq substr($alfabeto,$j,1) ) { 
$numero+=$j; 
break; 
} 
} 
} 
else  { 
$numero+=substr($codicefiscale,$i,1); 
} 
} 
 
$numero=$numero%26; 
$codicefiscale .= substr($alfabeto,$numero,1); 
 
return $codicefiscale ; 
} 

