From fb342ae5b3fc83c4f073ee4c433d5cf0ecaa96af Mon Sep 17 00:00:00 2001 From: fuligni <fuligni@netlab.fauser.edu> Date: Fri, 22 Apr 2022 13:41:39 +0200 Subject: [PATCH] Modifiche del 22/04/2022 --- iban.c | 216 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 iban.c diff --git a/iban.c b/iban.c new file mode 100644 index 0000000..16d7468 --- /dev/null +++ b/iban.c @@ -0,0 +1,216 @@ +/* + * 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; +} -- GitLab