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
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.
Comandi!
hehehe.. questo codice l'ho scritto io :)) sai com'e' a me piace ottimissare
al massimo :)
La spiegazione dice:
------------------
Un carattere alfabetico Carattere di controllo ottenuto convertemdo i
singoli caratteri in posizione pari secondo i valori della Tabella [A], ed i
caratteri in posizione dispari secondo i valori della Tabella [B].
Si sommano i valori ottenuti dalla conversione ed il totale lo si divide per
26.
Il resto della divisione lo si converte secondo la Tabella [C].
TABELLA [ A ] (caratteri in posizione 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
TABELLA [ B ] (caratteri in posizione 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
TABELLA [ C ] (conversione del carattere di controllo)
0=A 1=B 2=C 3=D 4=E 5=F 6=G 7=H 8=I 9=J
10=K 11=L 12=M 13=N 14=O 15=P 16=Q 17=R 18=S 19=T
20=U 21=V 22=W 23=X 24=Y 25=Z
------------------
In pratica se guardi la tabella [A] vedrai che ci sono più lettere che danno
lo stesso numero, ad esempio la lettera "C" vale 2, ma anche la lettera "2"
vale 2.
Lo scopo era creare un vettore nel quale posizionare le lettere
dell'alfabeto nella posizione del loro valore. Quindi la lettera "C" che
vale 2 doveva essere posizionata nella seconda posizione del vettore. Il
fatto che vi sono più lettere per uno stesso valore ho dato due posizioni
per ogni valore.
Il risultato sono le seguenti coppie:
B1 A0 KK PP LL C2 QQ D3 RR E4 VV OO SS F5 TT G6 UU H7 MM I8 NN J9 WW ZZ
YY XX
I caratteri "B" e "1" sono nella posizione 1 e quindi valgono 1
I caratteri "A" e "0" sono nella posizione 2 e quindi valgono 2
I caratteri "K" e "K" sono nella posizione 3. Solo "K" vale 3 quindi l'ho
scritta 2 volte ma si poteva anche scrivere qualcosa del tipo "K#" per
coprire la posizione non usata.
la stringa sarebbe potuta anche essere
"B1A0K#P#L#C2Q#D3R#E4V#O#S#F5T#G6U#H7M#I8N#J9W#Z#Y#X#" mettendo il "#" nelle
posizioni non utilizzate.
equivalente alle coppie:
B1 A0 K# P# L# C2 Q# D3 R# E4 V# O# S# F5 T# G6 U# H7 M# I8 N# J9 W# Z#
Y# X#
Con Instr trovo la posizione della lettera nella stringa e quindi il suo
valore. dato che vi sono 2 posizioni per valore basta dividere la posizione
trovata da instr per 2.
> TempNum = TempNum + ((AppoNum - 1) And &H7FFE) / 2
il "AND &7FFE" è una idiozia perchè serve per eliminare il bit meno
significativo e quindi renderlo sempre pari in modo che la /2 sia sempre
senza resto, ma in verità sarebbe bastato fare:
TempNum = TempNum + (AppoNum - 1) \ 2
usando l'operatore diviso backslash che divide e tronca il risultato
eliminando il resto.
heheh.. si si, qui non ho curato molto la leggibilità del codice :))
>
> 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
Ciao
Ettore Maronese, il Mes
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
> 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
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.
*Mai per comando!!* :-)), gentilissimo ettore......sei stato di una
chiarezza unica!!!
> hehehe.. questo codice l'ho scritto io :)) sai com'e' a me piace
ottimissare
> al massimo :)
Questo l'ho notato....io prima di leggere il tuo codice, avrei impostato
quelle tabelle con degli array.
In tal modo avrei impegnato piu' memoria??
[cut]
>
> > TempNum = TempNum + ((AppoNum - 1) And &H7FFE) / 2
>
> il "AND &7FFE" è una idiozia perchè serve per eliminare il bit meno
> significativo e quindi renderlo sempre pari in modo che la /2 sia sempre
Sarà un'idiozia, ma è molto interessante e quindi vorrei approfittare del
tuo grado di cortesia e competenza per chiederti se puoi spiegarmi più in
dettaglio questa operazione di *and* ....scusami per l'ignoranza:-)
> senza resto, ma in verità sarebbe bastato fare:
>
> TempNum = TempNum + (AppoNum - 1) \ 2
>
> usando l'operatore diviso backslash che divide e tronca il risultato
> eliminando il resto.
[cut]
Certamente questo modo e' molto più chiaro e semplice .
> Ciao
> Ettore Maronese, il Mes
Ciao e di nuovo grazie
Pino
Ciao,
> > hehehe.. questo codice l'ho scritto io :)) sai com'e' a me piace
> ottimissare
> > al massimo :)
>
> Questo l'ho notato....io prima di leggere il tuo codice, avrei impostato
> quelle tabelle con degli array.
> In tal modo avrei impegnato piu' memoria??
In verità la memoria usata sarebbe stata quasi identica, quello che cambia è
che usano dun array devi farti anche un loop di ricerca all'interno
dell'array, mentre io l'ho evitato utilizzando il comando instr$(). tutto
qui.
> [cut]
> >
> > > TempNum = TempNum + ((AppoNum - 1) And &H7FFE) / 2
> >
> > il "AND &7FFE" è una idiozia perchè serve per eliminare il bit meno
> > significativo e quindi renderlo sempre pari in modo che la /2 sia sempre
>
> Sarà un'idiozia, ma è molto interessante e quindi vorrei approfittare del
> tuo grado di cortesia e competenza per chiederti se puoi spiegarmi più in
> 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.
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....