Newsgroup: it.comp.lang.visual-basic
Titolo: [?]Calcolo codice fiscale

Dal sito comune mi sono scaricato un codice di esempio per il calcolo del
codice fiscale.
Non sono riuscito a capire la parte del codice  che calcola l'ultimo
carattere del codice fiscale, chiamato carattere di controllo.
Faccio presente di aver letto e capito come funzionano le tabelle (A-B-C) di
conversione, ma non mi e' chiaro il codice che fa riferimento a
queste tabelle.
Mi potreste dare una spiegazione sul funzionamento di questa parte di
codice?
Come viene ricavata la stringa presente nella funzione InStr?
Riporto il codice:
TempNum = 0
I = 1
Do
        ' I DISPARI
        AppoNum =
InStr("B1A0KKPPLLC2QQD3RRE4VVOOSSF5TTG6UUH7MMI8NNJ9WWZZYYXX", Mid(TxtCodFis,
I, 1))
       TempNum = TempNum + ((AppoNum - 1) And &H7FFE) / 2
        I = I + 1
        If I > 15 Then Exit Do
        ' I PARI
        AppoNum =
InStr("A0B1C2D3E4F5G6H7I8J9KKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ", Mid(TxtCodFis,
I, 1))
        TempNum = TempNum + ((AppoNum - 1) And &H7FFE) / 2
        I = I + 1
    Loop
Ciao e grazie a tutti
Pino

 codice?
Questo articolo è stato scritto tempo fa per un sito che trattava appunto
Visual Basic, spero possa esserti di aiuto.
Definizione
Il codice fiscale di una persona fisica è il codice alfanumerico che
distingue in modo univoco le persone iscritte nei registri dell'Anagrafe
Tributaria, cioè nel registro in cui sono conservati tutti i dati utili per
il funzionamento del sistema tributario; è composto da 16 caratteri di cui i
primi 15 rilevati dai dati anagrafici della persona (nome, cognome, sesso,
data e luogo di nascita) mentre il 16° è il carattere di controllo.
Composizione
I primi sei caratteri (partendo da sinistra) del codice fiscale indicano il
cognome (dal 1° al 3° carattere) ed il nome (dal 4° al 6° carattere).
Per l'estrazione dei caratteri dal cognome e dal nome occorre tener presente
alcune regole:
I cognomi, indipendentemente dalla loro composizione, devono essere
considerati come in un'unica successione di caratteri senza le eventuali
interruzioni (es.: Dell'Anno => DELLANNO; Di Biagio => DIBIAGIO) e per l'
estrazione dei caratteri si procede nel seguente modo:
ü nel caso in cui il cognome contenga tre o più consonanti devono essere
estratti, nell'ordine, la prima, la seconda e la terza consonante;
ü nel caso in cui il cognome contenga solo sue consonanti devono essere
estratti, nell'ordine, la prima e la seconda consonante e la prima vocale;
ü nel caso in cui il cognome contenga una sola consonante e due vocali
devono essere estratti, nell'ordina, la consonante e la prima e seconda
vocale;
ü nel caso in cui il cognome contenga una consonante ed una vocale, oppure
solo due vocali, devono essere estratti, nell'ordine, i caratteri e come
terzo carattere va impostata la lettera X.
I nomi, indipendentemente dalla loro composizione, devono essere considerati
come in un'unica successione di caratteri senza le eventuali interruzioni
(es.: Gian Maria => GIANMARIA) e per l'estrazione si procede nel seguente
modo:
ü nel caso in cui il nome contenga quattro o più consonanti devono essere
estratti, nell'ordine, la prima, la terza e la quarta consonante;
ü nel caso in cui il nome contenga solo tre consonanti devono essere
estratti, nell'ordine, la prima, la seconda e la terza consonante;
ü nel caso in cui il nome contenga solo due consonanti devono essere
estratti, nell'ordine, la prima e la seconda consonante e la prima vocale;
ü nel caso in cui il cognome contenga una sola consonante e due vocali
devono essere estratti, nell'ordine, la consonante e la prima e seconda
vocale;
ü nel caso in cui il cognome contenga una consonante ed una vocale, oppure
solo due vocali, devono essere estratti, nell'ordine, i caratteri così come
vengono e come terzo carattere va impostata la lettera X.
Esempio:
 CARATTERI
 1 2 3 4 5 6 7 8
Cognome: F A N T O Z Z I
Nome: U G O
Cognome: F N T
Nome: G U O
Stringa  F N T G U O
I successivi 5 caratteri (dal settimo all'undicesimo) rappresentano la data
di nascita della persona nel formato anno-mese-giorno e per la composizione
della stringa occorre tener presente le seguenti regole:
per l'anno devono essere indicate solo le ultime sue cifre (es. 1966 => 66)
e corrispondono al settimo ed all'ottavo carattere del codice;
per il mese, invece di indicare il numero corrispondete allo stesso (es. 01
=> Gennaio), si deve indicare il carattere corrispondete, così come rilevato
nella seguente tabella, e corrisponde al nono carattere del codice:
Gennaio A Maggio E Settembre P
Febbraio B Giugno H Ottobre R
Marzo C Luglio L Novembre S
Aprile D Agosto M Dicembre T
per il giorno devono essere indicati due caratteri, anteponendo lo zero
qualora il giorno di nascita sia costituita da una unità (es. 1 => 01). Nel
caso di persone di sesso femminile il giorno deve essere aumentato di 40
unità (es. 1 => 41).
Esempio:
Data di nascita: Giorno 20 20
 Mese Dicembre T
 Anno 1969 69
Stringa: 69T20
I successivi quattro caratteri, dal dodicesimo al quindicesimo indicano il
luogo di nascita della persone e corrispondono al codice del Comune rilevato
all'elenco dei comuni di Italia.
L'ultimo carattere, il sedicesimo, è il carattere di controllo e corrisponde
al valore del resto della divisione  della somma delle sommatorie dei valori
dei caratteri pari con la sommatoria dei caratteri dispari per 26.
Carattere di controllo =
Resto((C1+C3+C5+C7+C9+C11+C13+C15)+(C2+C4+C6+C8+C10+C12+C14)/26)
Il resto dell'operazione sopra descritta rappresenta il carattere di
controllo. I valori dei singoli caratteri vengono rilevati dalla seguente
tabella:
Carattere A B C D E F G H I J K L M N O P Q R
Posizione Pari 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
 Dispari 1 0 5 7 9 13 15 17 19 21 2 4 18 20 11 3 6 8
Carattere S T U V W X Y Z 1 2 3 4 5 6 7 8 9 0
Posizione Pari 18 19 20 21 22 23 24 25 1 2 3 4 5 6 7 8 9 0
 Dispari 12 14 16 10 22 25 24 23 0 5 7 9 13 15 17 19 21 1
Il carattere di controllo è rilevato dalla seguente tabella:
Resto Valore 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
 Carattere A B C D E F G H I J K L M N O P Q R
Resto Valore 18 19 20 21 22 23 24 25
 Carattere S T U V W X Y Z
Calcoliamo ora il Codice Fiscale del Signor FANTOZZI Ugo, sesso Maschile,
nato a Roma il 20/12/1966.
1) Estrazione dei caratteri del cognome:
Il cognome "FANTOZZI" è composto da più di tre consonanti, per cui
estrarremmo la prima, la seconda e la terza consonante : FNT
2) Estrazione dei caratteri del nome:
Il nome "UGO" è composto da una consonante e due vocali, per cui estrarremmo
l'unica consonante presente e le vocali nell'ordine di come vengono: GUO
3) Data di nascita:
I primi due caratteri indicano l'anno (66), il terzo il mese così come
indicato nella tabella (T) e gli ultimi due il giorno (20) : 66T20
4) Luogo di nascita:
Il codice del comune di nascita (Roma) rilevato dalla tabella è H501
5) Carattere di controllo:
la stringa fino ad ora ottenuta è la seguente: FNTGUO66T20H501. Ora, per
ricavare il carattere di controllo occorre, per prima cosa, sommare il
valore della sommatoria dei caratteri pari con il valore della sommatoria
dei caratteri dispari:
Posizione Carattere Valore carattere
  Dispari Pari
1 F 13
2 N  13
3 T 14
4 G  6
5 U 16
6 O  14
7 6 15
8 6  6
9 T 14
10 2  2
11 0 1
12 H  7
13 5 13
14 0  0
15 1 0
Sommatoria colonne 86 48
Totale (Dispari+Pari) 134
Il resto della divisione fra 134 e 26 (134/26) è uguale a 4 che corrisponde
alla lettera E.
Pertanto, il Codice Fiscale sarà il seguente:
Nel caso in cui la stringa alfanumerica relativa ai primi 15 caratteri sia
uguale per più soggetti diversi, vengono sostituiti uno o più caratteri
numerici i caratteri riportati nella seguente tabella:
Valore numerico 0 1 2 3 4 5 6 7 8 9
Carattere L M N P Q R S T U V
Note.
Il metodo per il calcolo del Codice Fiscale appenda descritto non è valido
nei casi in cui due o più persone siano omonime e siano nate nella stessa
città e nello stesso giorno. Anche se sembra impossibile ciò può capitare ed
in questo caso vengono apportate delle modifiche ai valori delle tabelle
indicate con dei valori in possesso solo ed esclusivamente dell'Anagrafe
Tributaria ed ai quali posso accedere solo i funzionari dell'anagrafe
stessa.
Benché abbia profuso tutta l'attenzione possibile nella redazione del
presente testo, l'autore declina ogni responsabilità di qualunque natura e/o
genere che dovesse derivare dall'inesattezza di quanto riportato nel
presente, nel database e nel programma. Il presente documento ed il relativo
programma è liberamente distribuibile sia per uso personale che per uso
commerciale.
Copyright © 2001 VbSimple.

 Pino
Ciao
Ettore Maronese, il Mes

  20=U 21=V 22=W 23=X 24=Y 25=Z
Ciao Ettore,
una domanda mi sorge spontanea...
La tabella [A] e la [C] sono "ovvie", la [A] è semplicemente:
Iif(c < "A", Asc(c)-38, Asc(c)-65) e la [C] è Chr$(n+65).
Però riesco a capire la [B]. Immagino che ci sia qualche
formula del tipo:    ValB = (X - Y * (Asc(c) - Z)) mod 26
però non ci sono riuscito ad "arrivare". Ne sai niente?
Ciao.
Mauro

 Mauro
Pultroppo non so l'origine di tali tabelle. Esse sono fornite così come sono
e per dirti il vero non ho nemmeno mai provato a cercarci una logica.


 Ettore Maronese, il Mes
Ciao e di nuovo grazie
Pino

 dettaglio questa operazione di *and* ....scusami per l'ignoranza:-)
Allora, TempNum è un intero. Qusto significa che è un numero composto da 2
bytes (16 bits ) che va da 0 a 65535 (senza segno) ma dato che gli interi in
VB sono con segno, viene utilizzato il bit più significativo per indicare il
negativo quindi l'intervallo è da -32768 a +32767.
Se pensi alla rappresentazione a BIT del numero 65 lo vedresti cos':
    0 000000001000001
Dove, da sinistra a destra hai lo zero che indica il segno (0=positivo,
1=negativo) e poi  le altre cifre che indicano il 65 in binario.
Se eseguo una operazione AND con la seguente maschera di bit (equivalente a
&H7FFE )
    0 111111111111110     ( 0111=&H7 ,  1111=&HF , 1111=&HF , 1110=&HE )
Accade che il risultato è quello di FORZARE il primo e l'ultimo bit a zero,
lasciando inalterati quelli centrali, ossia forzo il valore positivo (anche
se non serve) ed azzerando il bit più a destra forzo il valore ad essere un
multiplo di 2, ossia ad essere pari.
Il risultato è=
    0 000000001000001 AND
    0 111111111111110 =
    ----------------------
    0 000000001000000 = 64
Insomma, un AND per far diventare pari (per difetto) un valore intero.


 > > significativo e quindi renderlo sempre pari in modo che la /2 sia
sempre
[cut]

Grazie mille Ettore, non si finisce mai di imparare, anche in questo caso
sei stato molto chiaro.!!
Mi sto studiando un po' tutto il codice, nei ritagli di tempo....
