Il sedicesimo carattere del Codice Fiscale Italiano, ha la funzione di controllo dell’esatta trascrizione dei primi quindici caratteri.
Esso viene determinato nel modo seguente:
- Convertire in numeri tutti i caratteri che compongono il codice fiscale in posizione pari, rispettando i corrispondenti della tabella A;
- Convertire in numeri tutti i caratteri che compongono il codice fiscale in posizione dispari, rispettando i corrispondenti della tabella B;
- Addizionare tutti i numeri ottenuti dalla tabella A e B;
- Calcolare il resto della divisione tra la somma dei numeri e 26 (sommaNumeri % 26)
- Determinare la lettera alfabetica corrispondente al resto dell’operazione dalla tabella C.
Tabella A Per la conversione dei sette caratteri con posizione di ordine pari:
A o zero = zero O = 14 B o 1 = 1 P = 15 C o 2 = 2 Q = 16 D o 3 = 3 R = 17 E o 4 = 4 S = 18 F o 5 = 5 T = 19 G o 6 = 6 U = 20 H o 7 = 7 V = 21 I o 8 = 8 W = 22 J o 9 = 9 X = 23 K = 10 Y = 24 L = 11 Z = 25 M = 12 - - N = 13 - -
Tabella B Per la conversione degli otto caratteri con posizione di ordine dispari:
A o zero = 1 O = 11 B o 1 = 0 P = 3 C o 2 = 5 Q = 6 D o 3 = 7 R = 8 E o 4 = 9 S = 12 F o 5 = 13 T = 14 G o 6 = 15 U = 16 H o 7 = 17 V = 10 I o 8 = 19 W = 22 J o 9 = 21 X = 25 K = 2 Y = 24 L = 4 Z = 23 M = 18 - - N = 20 - -
Tabella C I valori numerici determinati vengono addizionati e la somma si divide per il numero 26. Il carattere di controllo si ottiene convertendo il resto di tale divisione nel carattere alfabetico ad esso corrispondente nella tabella:
zero = A 14 = O 1 = B 15 = P 2 = C 16 = Q 3 = D 17 = R 4 = E 18 = S 5 = F 19 = T 6 = G 20 = U 7 = H 21 = V 8 = I 22 = W 9 = J 23 = X 10 = K 24 = Y 11 = L 25 = Z 12 = M - - 13 = N - -
Algoritmo in Kotlin
//Corrispettivi caratteri codice fiscale in posizione pari
private val charInEvenPosition = mapOf(
"0" to 0, "1" to 1, "2" to 2,
"3" to 3, "4" to 4, "5" to 5,
"6" to 6, "7" to 7, "8" to 8,
"9" to 9, "A" to 0, "B" to 1,
"C" to 2, "D" to 3, "E" to 4,
"F" to 5, "G" to 6, "H" to 7,
"I" to 8, "J" to 9, "K" to 10,
"L" to 11, "M" to 12, "N" to 13,
"O" to 14, "P" to 15, "Q" to 16,
"R" to 17, "S" to 18, "T" to 19,
"U" to 20, "V" to 21, "W" to 22,
"X" to 23, "Y" to 24, "Z" to 25
)
//Corrispettivi caratteri codice fiscale in posizione dispari
val charInOddPosition = mapOf(
"0" to 1, "1" to 0, "2" to 5,
"3" to 7, "4" to 9, "5" to 13,
"6" to 15, "7" to 17, "8" to 19,
"9" to 21, "A" to 1, "B" to 0,
"C" to 5, "D" to 7, "E" to 9,
"F" to 13, "G" to 15, "H" to 17,
"I" to 19, "J" to 21, "K" to 2,
"L" to 4, "M" to 18, "N" to 20,
"O" to 11, "P" to 3, "Q" to 6,
"R" to 8, "S" to 12, "T" to 14,
"U" to 16, "V" to 10, "W" to 22,
"X" to 25, "Y" to 24, "Z" to 23
)
//Corrispettivi risultato del resto della divisione
private val controlChar = mapOf(
0 to "A", 1 to "B", 2 to "C",
3 to "D", 4 to "E", 5 to "F",
6 to "G", 7 to "H", 8 to "I",
9 to "J", 10 to "K", 11 to "L",
12 to "M", 13 to "N", 14 to "O",
15 to "P", 16 to "Q", 17 to "R",
18 to "S", 19 to "T", 20 to "U",
21 to "V", 22 to "W", 23 to "X",
24 to "Y", 25 to "Z"
)
private fun checkControlLetterFiscalCode(fiscalCode: String): Boolean {
var numberCharInEvenPosition = 0
var numberCharInOddPosition = 0
val fiscalCodeWithOutControlLetter = fiscalCode.substring(0, (fiscalCode.length - 1));
for (i in fiscalCodeWithOutControlLetter.indices) {
//Calcolo il modulo della i-esima posizione
//Il calcolo prevede che la prima posizione sia identificata con 1 e non con 0
val isEven = (i+1) % 2
//Conversione carattere in stringa e in lettera maiuscola
val char = fiscalCode[i].toUpperCase().toString()
//determino se la posizione è pari o dispari e ottengo il corrispettivo dalle tabelle
when(isEven){
0 -> numberCharInEvenPosition += charInEvenPosition[char] ?: error("error")
else -> numberCharInOddPosition += charInOddPosition[char] ?: error("error")
}
}
//Calcolo del numero di controllo attraverso la formula data
val controlNumber = (numberCharInEvenPosition + numberCharInOddPosition) % 26
//Ottengo la corrispettiva lettera associata al numero ottenuto dal resto della divisione
val controlChar = controlChar[controlNumber]
//Determino la lettera di controllo presente nel codice fiscale inserito
val currentControlChar = fiscalCode[fiscalCode.length-1].toUpperCase().toString()
//Controllo l'uguaglianza tra la lettera di controllo inserita nel codice fiscale e quella calcolata con l'algoritmo
return controlChar == currentControlChar
}