In questa lezione implementeremo il cifrario di Cesare da file.
Nella scorsa lezione abbiamo implementato semplicemente l’algoritmo per il cifrario di Cesare inserendo un testo da tastiera lungo massimo 100 caratteri, potete consultare la lezione al link: il cifrario di Cesare in C.
Oggi ci occuperemo invece di scrivere un programma che simuli il cifrario di Cesare sia per il mittente che per il destinatario.
Il testo è salvato in un file, ad esempio di nome testo.txt. Il mittente, dopo averlo cifrato lo salva in un altro file di testo di nome testocifrato.txt.
Il destinatario legge il file testocifrato.txt, decifra il messaggio e lo salva nel file testodecifrato.txt.
Per semplicità consideriamo il messaggio senza spazi vuoti, senza accenti, senza punteggiatura, lungo 14 caratteri e tutto in maiuscolo.
Immaginiamo dunque che nel file di testo ci sia scritto CODINGCREATIVO. Questo è dunque il testo che deve essere cifrato in base alla chiave digitata in input dal mittente.
Sviluppiamo quindi le seguenti funzioni:
void stampaAlfabeto(int c); Si occupa di stampare l’alfabeto cifrato in base alla chiave fornita in input.
void messCifrato(char testo[n],int c); Si occupa di cifrare la frase presa in input in base alla chiave fornita in input.
void messDecifrato(char testo[n],int c); Si occupa di decifrare la frase presa in input in base alla chiave fornita in input.
Ecco l’algoritmo per il cifrario di Cesare da file:
#include <stdio.h>
#define n 14
void stampaAlfabeto(int c);
void messCifrato(char testo[n],int c);
void messDecifrato(char testo[n],int c);
int main(int argc, char *argv[]) {
int c,i;
char testo[n+1];
FILE *input;
FILE *input2;
do {
printf("--> MITTENTE\n\tInserisci la chiave: ");
scanf("%d",&c);
} while(c<=0 || c>26);
stampaAlfabeto(c); //stampa il nuovo alfabeto
input=fopen("Testo.txt","r"); //apriamo il file in lettura
fscanf(input,"%s",testo);
fclose(input);
printf("\tTesto in chiaro letto da file: %s\n", testo);
messCifrato(testo,c);
printf("\n-->DESTINATARIO \n");
input2=fopen("TestoCifrato.txt","r");
fscanf(input2,"%s",testo);
fclose(input2);
printf("\tTesto cifrato letto dal file : %s\n", testo);
messDecifrato(testo,c);
printf("\n");
return 0;
}
void stampaAlfabeto(int c) {
int i, cont=65;
char cifrato[26];
printf("\tAlfabeto cifrato con chiave %d: \n\t", c);
for(i=0;i<26-c;i++) {
cifrato[i]=cont+c;
printf("%c ",cifrato[i]);
cont++;
}
printf("\n\n");
}
void messCifrato(char testo[n+1],int c) {
int i;
FILE *output;
for(i=0;i<n;i++)
if(testo[i]<'Z'-c)
testo[i]+=c;
else
testo[i]='A'+c-('Z'-testo[i])-1;
printf("\n");
output=fopen("TestoCifrato.txt","w"); //apro il file
fprintf(output,"%s",testo);
fclose(output);
printf("\tTesto cifrato scritto su file: %s\n", testo);
}
void messDecifrato(char testo[n+1],int c) {
int i;
FILE *output2;
for(i=0;i<n;i++)
if(testo[i]<'A'+c)
testo[i] = 'Z'-(c-(testo[i]-'A')-1);
else
testo[i]-=c;
output2=fopen("TestoDecifrato.txt","w");
fprintf(output2,"%s",testo);
fclose(output2);
printf("\tTesto decifrato scritto su file: %s\n", testo);
}
In questa lezione implementeremo un algoritmo per il cifrario di Cesare in C.
Il cifrario di Giulio Cesare è un facile esempio di crittografia a sostituzione, cioè dove ciascun elemento del testo è trasformato in un altro elemento.
All’epoca di Giulio Cesare era un algoritmo efficace e veniva usato per inviare le sue corrispondenze.
Quindi si sceglieva una chiave numerica ed in base a questa chiave ogni lettera veniva sostituita dalla lettera indicata dalla chiave.
Facciamo quindi un esempio:
Alfabeto non cifrato: A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z.
Assegniamo alla chiave numerica il valore 5.
L’alfabeto cifrato diventa così: F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, A, B, C, D, E.
Il cifrario si realizza dunque in modo circolare, quando si arriva alla Z si riparte dalla A.
L’algoritmo quindi risulta molto semplice e proprio per questo è una tecnica che può essere facilmente violata. Infatti si può andare facilmente a tentativi, in quanto le possibili chiavi sono 26.
Si è cercato di superare questi limiti assegnando a ciascuna lettera del testo in chiaro una lettera scelta a caso. Così abbiamo ben 26! possibili chiavi. Ma rimaneva sempre un punto debole in quanto ogni lettera veniva sostituita sempre dalla stessa lettera.
Algoritmo per il cifrario di Cesare in C
Ecco dunque l’algoritmo sul cifrario di Cesare in linguaggio C che prende in input un testo scritto in maiuscolo e senza spazi e restituisce il messaggio cifrato.
Quindi leggiamo la lunghezza del testo inserito:
while(testo[n]!= '\0') //finchè non arriviamo alla fine del testo
n++;
Dunque, con un ciclo for, convertiamo ciascun carattere aggiungendo la chiave inserita a ciascuna lettera facendo attenzione che, quando si arriva alla posizione Z – la chiave, dobbiamo iniziare nuovamente dalla lettera A e dobbiamo aggiungere la posizione della chiave meno le posizioni che rimanevano per arrivare alla lettera Z.
testoc[i]=’A’+c-(‘Z’-testo[i])-1;
Dopo, allo stesso modo, decifriamo il testo per ottenere ciò che avevamo inserito in input.
#include<stdio.h>
#define MAX 100
int main(){
int i,n,c;
char testo[MAX],testoc[MAX],testod[MAX];
printf("Inserisci la frase in maiuscolo e senza spazi: ");
gets(testo);
if(testo[i]>='A' && testo[i]<='Z') {
do{
printf("Chiave: ");
scanf("%d",&c);
}while(c<0 || c>26);
while(testo[n]!= '\0')
n++;
for(i=0;i<n;i++)
if(testo[i]<'Z'-c)
testoc[i]=testo[i]+c;
else
testoc[i]='A'+c-('Z'-testo[i])-1;
testoc[n] = '\0';
printf("Testo criptato : %s\n",testoc);
for(i=0;i<n;i++)
if(testoc[i]<'A'+c)
testod[i] = 'Z'-(c-(testoc[i]-'A')-1);
else
testod[i] = testoc[i] - c;
testod[n] = '\0';
printf("Testo decriptato: %s\n",testod);
}
else
printf("Errore il testo deve essere maiuscolo e senza spazi vuoti\n");
}
Nella prossima lezione svilupperemo l’algoritmo sul cifrario di Cesare, leggendo il testo da un file.
Affronteremo in questa lezione alcuni semplici esercizi sulla selezione con Scratch.
Primo esercizio sulla selezione con Scratch
Il primo degli esercizi sulla selezione che vi voglio proporre oggi è:
Dati due numeri A e B verificare se A è il quadrato di B.
Procedimento
Scegliamo uno sfondo ed uno sprite qualsiasi e chiediamo di inserire in input due numeri.
Dopo andiamo su controlloe utilizziamo il blocco se allora altrimenti per controllare se a è il doppio di b.
Quindi visualizziamo il risultato in output.
Infine inseriamo il blocco ferma tutto.
Ecco dunque il codice a blocchi completo:
Ecco l’algoritmo sviluppato in linguaggio C++:
#include <iostream>
using namespace std;
int main() {
int a, b;
cout<<"Inseriamo il primo numero: ";
cin>>a;
cout<<"Inseriamo il secondo numero: ";
cin>>b;
if(a==b*b)
cout<<a<<" e' il quadrato di "<<b<<endl;
else
cout<<a<<" non e' il quadrato di "<<b<<endl;
return 0;
}
Secondo esercizio sulla selezione con Scratch
Il secondo degli esercizi sulla selezione che affronteremo in questa lezione è:
Determinare se un numero naturale A è il precedente del numero naturale B.
Il procedimento è molto analogo al precedente.
Quindi chiediamo in input i due numeri, andiamo su controlloe utilizziamo il blocco se allora altrimenti per controllare se a è uguale a b-1.
Ecco dunque il codice a blocchi completo:
Ecco dunque l’algoritmo sviluppato in linguaggio C++:
#include <iostream>
using namespace std;
int main() {
int a, b;
cout<<"Inseriamo il primo numero: ";
cin>>a;
cout<<"Inseriamo il secondo numero: ";
cin>>b;
if(a==b-1)
cout<<a<<" e' il precedente di "<<b<<endl;
else
cout<<a<<" non e' il precedente di "<<b<<endl;
return 0;
}
In questa lezione svilupperemo un algoritmo per il calcolo del maggiore fra tre numeri con Scratch 3.
Nella scorsa lezione abbiamo studiato l’algoritmo per determinare il maggiore tra due numeri, in questa lezione determineremo il massimo fra tre numeri.
Quindi chiediamo in input tre numeri: a, b e c e poniamo la variabile max uguale ad a.
Dopo controlliamo se b è maggiore del massimo e se è vero portiamo la variabile max uguale a b.
Poi controlliamo se c è maggiore del massimo e se è vero portiamo la variabile max uguale a c.
Infine visualizziamo il valore massimo.
Un altro procedimento, per il calcolo del maggiore fra tre numeri, può essere questo:
Confrontare il numero a con b:
se a>b è verodunque possiamo escludere b e confrontare a con c:
se a>c è vero il maggiore è dunque a; se è falso il maggiore è c.
se a>b è falso dunque possiamo escludere a e confrontare b con c:
se b>c è vero il maggiore è b; altrimenti è c
Ecco dunque l’algoritmo completo:
Allego il programma che calcola il massimo tra tre numeri in C++, per chi volesse consultarlo.
#include <iostream>
using namespace std;
int main() {
int a, b, c, max;
cout<<"Inseriamo il primo numero: ";
cin>>a;
cout<<"Inseriamo il secondo numero: ";
cin>>b;
cout<<"Inseriamo il terzo numero: ";
cin>>c;
max=a;
if(b>max)
max=b;
if(c>max)
max=c;
cout<<"Il massimo e':"<<max<<endl;
return 0;
}
Potrei anche escludere la variabile a e utilizzare direttamente la variabile max in questo modo:
cout<<"Inseriamo il primo numero: ";
cin>>max;
Secondo procedimento per il calcolo del massimo fra tre numeri in C++:
#include <iostream>
using namespace std;
int main() {
int a, b, c;
cout<<"Inseriamo il primo numero: ";
cin>>a;
cout<<"Inseriamo il secondo numero: ";
cin>>b;
cout<<"Inseriamo il terzo numero: ";
cin>>c;
if(a>b)
if(a>c)
cout<<"Il massimo e': "<<a<<endl;
else
cout<<"Il massimo e': "<<c<<endl;
else
if(b>c)
cout<<"Il massimo e': "<<b<<endl;
else
cout<<"Il massimo e': "<<c<<endl;
return 0;
}
Realizziamo un semplice algoritmo per il calcolo del maggiore tra due numeri in Scratch.
Scegliamo uno sfondo ed uno sprite qualsiasi.
1 – Inizio: andiamo su situazionie scegliamo quando si clicca sulla bandiera verde.
2 – Andiamo su sensorie scegliamo il blocco chiedi ‘Come ti chiami?’ e attendi. Sostituiamo al posto di Come ti chiami? il testo Inserisci il primo numero.
3 – Andiamo su variabilie creiamo la variabile di nome a, lasciando l’opzione per tutti gli sprite. (Per creare una nuova variabile vi ricordo il tutorial: variabili in scratch 3.0)
4 -Trasciniamo il blocco porta a a.
5 – Inseriamo il blocco risposta che si trova nella sezione sensori.
6 – Ripetiamo i passi 2, 3, 4 e 5 per la variabile b.
7 – Andiamo su controllo e scegliamo il blocco se allora altrimenti.
8 – Operatori: trasciniamo il blocco con il simbolo >.
8 – Andiamo su dire e se a è maggiore di b allora visualizziamo in output il messaggio.
9 – Altrimenti inseriamo un altro blocco di controllose allora altrimenti.
10 – Operatori: trasciniamo il blocco con il simbolo =
11 – Andiamo su diree se a è uguale a b allora visualizziamo in output il messaggio.
12 – Altrimenti sempre su direinseriamo il messaggio che a è minore di b.
13 – Fine: andiamo su controllo e scegliamo ferma tutto.
Ecco quindi il codice a blocchi per l’algoritmo che calcola il maggiore tra due numeri:
Nella prossima lezione svilupperemo l’algoritmo per il calcolo del maggiore fra tre numeri presi in input.