/* * File: iban.c * * Autore: Roberto FULIGNI * Ultima modifica: 22/04/2022 * * Descrizione: Calcolo dei codici BBAN e IBAN * di un conto corrente italiano. */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #define MAX_ABI 5 #define MAX_CAB 5 #define MAX_CONTO 12 #define MAX_BBAN 23 #define MAX_IBAN (MAX_BBAN + 4) #define MAX_TABELLA 36 char TABELLA[MAX_TABELLA+1] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int VAL_PARI[MAX_TABELLA] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}; int VAL_DISPARI[MAX_TABELLA] = {1, 0, 5, 7, 9, 13, 15, 17, 19, 21, 1, 0, 5, 7, 9, 13, 15, 17, 19, 21, 2, 4, 18, 20, 11, 3, 6, 8, 12, 14, 16, 10, 22, 25, 24, 23}; // La funzione cin_italiano riceve in ingresso una stringa // contenente un codice BBAN e restituisce il CIN italiano char cin_italiano(char bban[]) { int lung_bban = strlen(bban); if (lung_bban != MAX_BBAN) { printf("Codice BBAN non valido\n"); exit(1); } // Si calcola il CIN a partire dal secondo carattere, tralasciando così // l'eventuale cin gia' presente int somma = 0; for(int i = 1; i < lung_bban; i++) { // Individua la posizione del carattere i-esimo scandendo la tabella // dall'ultimo carattere al primo int pos = MAX_TABELLA - 1; while (pos >= 0 && TABELLA[pos] != toupper(bban[i])) pos--; if (pos < 0) { printf("Il codice BBAN contiene un carattere non valido: %c\n", bban[i]); exit(1); } if (i % 2 == 0) // Posizione pari somma += VAL_PARI[pos]; else somma += VAL_DISPARI[pos]; } int resto = somma % 26; char cin = 'A' + resto; return cin; } // Funzione calcola_bban // // Parametro di output: codice BBAN elaborato // Parametri di input: codici ABI e CAB, conto corrente void calcola_bban(char bban[], char abi[], char cab[], char conto[]) { if (strlen(abi) != MAX_ABI) { printf("Codice ABI non valido\n"); exit(1); } if (strlen(cab) != MAX_CAB) { printf("Codice CAB non valido\n"); exit(1); } int lung_conto = strlen(conto); if (lung_conto == 0 || lung_conto > MAX_CONTO) { printf("Numero di conto corrente non valido\n"); exit(1); } // Si copia il contenuto a partire dalla seconda posizione (indice zero-based) // tralasciando così, per il momento, il CIN italiano bban[0] = ' '; int pos = 1; for(int i = 0; i < MAX_ABI; i++) { bban[pos] = abi[i]; pos++; } for(int i = 0; i < MAX_CAB; i++) { bban[pos] = cab[i]; pos++; } // Copiamo ora il numero di conto, partendo dall'ultima cifra (quella più a destra) // fino alla prima: in questo potremo aggiungere alla fine gli eventuali zeri di padding pos = MAX_BBAN - 1; for (int i = lung_conto - 1; i >= 0; i--) { bban[pos] = conto[i]; pos--; } int num_zeri = MAX_CONTO - lung_conto; while (num_zeri > 0) { bban[pos] = '0'; pos--; num_zeri--; } char cin = cin_italiano(bban); bban[0] = cin; // Inserisco il terminatore di stringa bban[MAX_BBAN] = '\0'; } // La funzione cin_europeo riceve in ingresso due stringhe // contenenti un codice di nazione e un codice BBAN. // Restituisce un numero rappresentante il CIN europeo int cin_europeo(char nazione[], char bban[]) { if (strlen(nazione) != 2) { printf("Codice di nazione non valido\n"); exit(1); } int lung_bban = strlen(bban); if(strcmp(nazione, "IT") == 0 && lung_bban != MAX_BBAN) { printf("Codice BBAN non valido\n"); exit(1); } int lung_buffer = MAX_BBAN + 4; char buffer[lung_buffer+1]; strcpy(buffer, bban); strcat(buffer, nazione); strcat(buffer, "00"); int somma = 0; for(int i = 0; i < lung_buffer; i++) { char c = toupper(buffer[i]); int val; if (isdigit(c)) { val = c - '0'; somma = somma * 10 + val; } else if (isalpha(c)) { val = c - 'A' + 10; somma = somma * 100 + val; } else { printf("Carattere non valido: %c\n", c); exit(1); } // Alla fine di ogni iterazione si riduce il valore della somma somma = somma % 97; } int cin = 98 - somma; return cin; } // Funzione calcola_iban // // Parametro di output: codice IBAN elaborato // Parametri di input: codice nazione, codice BBAN void calcola_iban(char iban[], char nazione[], char bban[]) { if (strlen(nazione) != 2) { printf("Codice di nazione non valido\n"); exit(1); } if(strcmp(nazione, "IT") == 0 && strlen(bban) != MAX_BBAN) { printf("Codice BBAN non valido\n"); exit(1); } int cin_eu = cin_europeo(nazione, bban); char str_cin[3]; str_cin[0] = '0' + (cin_eu / 10) % 10; // Cifra delle decine str_cin[1] = '0' + (cin_eu) % 10; // Cifra delle unita' str_cin[2] = '\0'; // Terminatore strcpy(iban, nazione); strcat(iban, str_cin); strcat(iban, bban); } int main() { char abi[6] = "08327"; char cab[6] = "38941"; char cc[13] = "172964"; char nazione[3] = "IT"; char bban[MAX_BBAN+1]; char iban[MAX_IBAN+1]; calcola_bban(bban, abi, cab, cc); printf("BBAN: %s\n", bban); calcola_iban(iban, nazione, bban); printf("IBAN: %s\n", iban); return 0; }