Macchina enigma per esame di stato

salve, sono nuovo e sono un principiante. mi sto approcciando da pochi mesi al mondo di arduino, e vorrei portare all’esame di stato un piccolo progetto, su cui incentro tutta la mia tesina, una macchina enigma.
uso come componenti: tre led (verde, giallo, rosso), un ricevitore IR con telecomando, display e potenziometro
ho già sviluppato un po di programma. sono riuscito a fare la sequenza di sblocco della macchina enigma, dove viene confrontata la sequenza data da me con quella predefinita.

il programma inizia cosi:

  • i tre led si accendono e poi si spegnano, facendo capire che il programma è partito.

-sul display LCD, esce scritto ‘‘Inserire pin’’, cosi si può iniziare ad inserire una sequenza che poi sarà confrontata con quella predefinita per sbloccare la macchina.

-ad ogni input dato dal telecomando, corrisponde un blink giallo, arrivati a 4 numeri, viene confrontata la sequenza, per dirmi infine se la password è giusta o meno.

ora non so come andare avanti.
l’idea è quella di associare ad ogni numero del telecomando IR una lettera dell’alfabeto (tipo 1=a, 2=b, ecc…), naturalmente, inserisco un numero e dopo clicco il pulsante POWER, come se fosse il pulsante INVIO del Pc, questo per prevenire errori quanto inserisco i numeri a due cifre, quindi l’arduino aspetta fino a quando non gli do l’input del tasto POWER, per convertirlo poi nella lettera corrispondente.

cosi l’idea di criptografia è inserire determinati numeri che corrispondono alle lettere dell’alfabeto, per poi essere convertite dall’arduino, che mi mostra la parola decriptata sul display LCD.

cosi si forma una parola, una macchina enigma semplice, non complessa.
vi prego, aiutatemi, sono leggermente nel panico visto che gli esami sono alle porte.
vi allego il file di quello che ho programmato

#include "IRremote.h"
#include <LiquidCrystal.h>

LiquidCrystal lcd (2,3,4,5,6,7);

int ricevitore=11;
int sequenza[]={3,4,5,6};
int codice[4];
/*
 ho solo portato i led a 3
*/
int ledrosso=8;
int ledgiallo=9;
int ledverde=10;
int counter = 0;
/*
 questi due servono uno per l'assegnamento della funzione
 dimmipulsanti e l'altro per la sequenza dei led
*/
int risultato = 0;
int intro = 0;

boolean t=true;
IRrecv irrecv(ricevitore);    
decode_results results;


/*
   Invece di fare un return che con il telecomando
   tramite il monitor seriale ho notato desse risultati
   imprevedibili, usiamo una variabile così da avere
   un risultato preciso
*/
int dimmipulsanti()
{
   switch(results.value){
       case 0xFF6897:   risultato = 00;   break;
       case 0xFF30CF:   risultato = 1;   break;
       case 0xFF18E7:   risultato = 2;  break;
       case 0xFF7A85:   risultato = 3;  break;
       case 0xFF10EF:   risultato = 4;  break;
       case 0xFF38C7:   risultato = 5;  break;
       case 0xFF5AA5:   risultato = 6;  break;
       case 0xFF42BD:   risultato = 7; break;
       case 0xFF4AB5:   risultato = 8;  break;
       case 0xFF52AD:   risultato = 9;  break;
       default:
          risultato = 10;

   }

   delay(500);
   /*
     delay tra le letture, per stessa ammissione
     della elegoo il ricevitore ir fa un poco
     schifo, e potrebbe segnalare un falso
     positivo sul pulsante premuto
   */

}
void setup() {
   Serial.begin(9600);
   irrecv.enableIRIn();
   pinMode(ledrosso,OUTPUT);
   pinMode(ledverde,OUTPUT);
   pinMode(ledgiallo,OUTPUT);
   /*
     ho usato 3 led di colore diverso
     per farti rendere conto dei vari passaggi
   */
    lcd.begin(16, 2);
    lcd.print("Inserire pin");

}

void loop() {
 /*
   È una semplice sequenza per farti capire che
   il loop è ricominciato
 */

     if(intro == 0)
         {
             delay(500);
             digitalWrite(ledrosso, HIGH);
             delay(500);
             digitalWrite(ledgiallo, HIGH);
             delay(500);
             digitalWrite(ledverde, HIGH);
             delay(500);
             digitalWrite(ledrosso, LOW);
             digitalWrite(ledgiallo,LOW);
             digitalWrite(ledverde,LOW);
             intro = 1;
         }
    
     if(irrecv.decode(&results))
     {
    
         dimmipulsanti(); // questa volta lo usiamo così perchè assegnamo una variabile nella funzione
         codice[counter] = risultato; // e la scriviamo nell'array
         /*
           se apri il serial monitor queste due
           righe di codice ti fanno vedere il
           valore che hai appena messo e il
           valore del counter
         */

         lcd.setCursor(0,1);
         lcd.print(codice[counter]);
         digitalWrite(ledgiallo, HIGH);   // accendo un attimo il led per mezzo secondo
         delay(200);
         digitalWrite(ledgiallo, LOW); // lo spengo
         delay(200);
         counter++;
         irrecv.resume();

          
            
        
        
         if(counter == 4) //se abbiamo inserito 4 cifre
             {
                 counter = 0;
                 intro = 0;
                 for(int a=0;a<4;a++){  
                 t= codice[a] == sequenza[a];
                    }
                    if(t==true){
                     digitalWrite(ledverde,HIGH);
                     lcd.setCursor(0, 1);
                     lcd.print("Password giusta");
                     delay(1000);
                     digitalWrite(ledverde,LOW);
                        for(int b=0;b<16;b++){
                           lcd.setCursor(b,1);
                           lcd.print(' ');
                         } 
                     
                    }
                   
                    else{
                     digitalWrite(ledrosso,HIGH);
                     lcd.setCursor(0, 1);
                     lcd.print("Password errata");
                     delay(1000);
                     digitalWrite(ledrosso,LOW);
                        for(int b=0;b<16;b++){
                           lcd.setCursor(b,1);
                           lcd.print(' ');
                         } 
                     
                    }
             }                   

    }
}

sketch_mar03b.ino (4.25 KB)

I nuovi utenti si devono presentare nell'apposita sezione o non riceveranno aiuto!
Essendo il tuo primo post, presentati dicendo quali conoscenze hai di elettronica e programmazione :slight_smile:

Ti dico che il progetto non ha niente a che fare con la macchina enigma, un nome ad effetto ma poi se trovi qualcuno all'esame che ha una minima idea di cosa sia una macchina enigma "basta solo pensare che ci sono voluti le migliori menti per poterla decifrare". Visto che ha fatto fatica Turing a capirci qualcosa, mi sembra alquanto pretenzioso che un maturando possa conoscerla al punto di replicarla :slight_smile:

Il tuo progetto è un semplice riconoscimento password molto elementare. Per cui o cambi progetto o cambi nome :slight_smile:

Detto questo, il problema è nella verifica della password, nel confronto di uguaglianza di due array, che è sbagliato e non può funzionare.

premetto che non sapevo che dovevo presentarmi.
la password la riconosce, il mio problema sta nell'associare i numeri del telecomando con delle lettere, cioe il messaggion cifrato sarebbe (3-9-1-13=CIAO).
Un esempio molto stupido e basilare di una macchina enigma, perchè comunque non ho tutte le componenti

>stefno: … NON avendolo tu ancora fatto, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione … possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO

… poi, in conformità al suddetto regolamento, punto 7, devi editare il tuo post (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More → Modify che si trova in basso a destra del tuo post) e racchiudere il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Guglielmo

P.S.: NON potrai ricevere ulteriori risposte alle tue domande sino a quando le due cose non saranno state sistemate.

Salve, mi scuso , se non ho fatto prima tutte queste cose, ora ho capito.
Penso di aver editato bene il codice e inoltre mi sono presentato nella sezione che lei mi ha indicato.

Penso di aver fatto tutto, ora posso partecipare al forum? Potete aiutarmi?

stefno:
Penso di aver fatto tutto, ora posso partecipare al forum? Potete aiutarmi?

Tutto a posto, grazie mille ... chiunque possa aiutarti sicuramente lo farà :slight_smile:

Nel frattempo ti consiglio di spiegare molto bene ciò che vuoi ottenere (magari con una descrizione punto a punto delle varie fasi) perché ... almeno io, leggendo il tuo primo post, NON ho ben capito il funzionamento che vuoi ottenere, l'uso dei LED, l'algoritmo di codifica, ecc. ecc. :wink:

Guglielmo

Ciao :slight_smile:
I problemi risolviamoli tutti ! Anche perché hai detto che vuoi fare informatica quindi incominciamo subito :slight_smile:

QUESTO è IL TUO CODICE

for(int a=0;a<4;a++){  
                 t= codice[a] == sequenza[a];
                    }
                    if(t==true){
                     digitalWrite(ledverde,HIGH);
                     lcd.setCursor(0, 1);
                     lcd.print("Password giusta");
                     delay(1000);
                     digitalWrite(ledverde,LOW);
                        for(int b=0;b<16;b++){
                           lcd.setCursor(b,1);
                           lcd.print(' ');
                         } 
                     
                    }

Cosa succederebbe se a metà del codice trovasse un numero diverso ma l’ultimo numero è uguale a quello voluto.
Quello che succede è che la variabile t si diventa false, ma poi basta che l’ultimo numero sia giusto e diventa vera. Quindi questo codice darà sempre true basta che l’ultimo numero sia uguale.

Io modificherei cosi

t=true; // Se non diventa falso vuol dire che il codice è giusto

for(int a=0;a<4;a++){  
    if(codice[a]!=sequenza[a]){
         t=false;// Il codice è sbagliato
         break; // Esco dal ciclo e t rimane false
     }
 }                  

 if(t==true){
                     digitalWrite(ledverde,HIGH);
                     lcd.setCursor(0, 1);
                     lcd.print("Password giusta");
                     delay(1000);
                     digitalWrite(ledverde,LOW);
                        for(int b=0;b<16;b++){
                           lcd.setCursor(b,1);
                           lcd.print(' ');
                         } 
  }

Per associare un numero a una lettera puoi usare uno switch() a ogni numero corrisponde una lettera.

Puoi crearti un array MessaggioCifrato[5], scorri l'array codice con un ciclo for(), e con uno switch() ricavi la lettera da numero. Avendo la lettera l'assegni all'array MessaggioCifrato, con lo stesso indice di array codice.

Grazie mille, non avevo notato questo problema.

Ora per il fatto di associare i numeri alle lettere, numeri inseriti tramite il telecomandino.

Naturalmente, io avevo pensato di creare all’interno tipo una leggenda dove veniva scritto che ad ogni numero corrispondeva una determinata lettera. quello che doveva fare l’arduino è convertire quel numero in lettera, cosi da una sequenza di numeri si ha una sequenza di lettere che è una parola.

Grazie in anticipo.

Be quello che vuoi, come ti ho spiegato lo puoi fare con uno switch() case!

Resta il dubbio!? Perché non lavorare direttamente e solo con i caratteri ? Perché usare numeri interi e poi confrontarli.

Esempio nel tuo codice hai uno switch() che in base a un numero esadecimale ricava un numero intero!
Bene potresti ricavare dallo switch() direttamente un carattere, numeroEsadecimale=carattere.

A questo punto il programma andrebbe riveduto, in quanto per confrontare due stringhe esiste la funzione strcmp(), if(strcmp(Codice,"miapassword")==0) allora se uguale faccio qualcosa.

Domanda:
Non potremmo, invece, fare un array ci char lungo N(dove N=numero di codici accettati) e riempirlo con la lettera associata ad ogni singolo codice?(vale a dire che se, ad esempio,

1=A, 2=B, 3=C, 4=D

Diventa

char traduzioni [5]={' ' 'A, 'B','C,'D'};
//ho usato il carattere spazio per indicare elemento vuoto, perché ricordiamo che gli array partono dall'elemento 0
//se non si volesse si potrebbe "limare" l'array stabilendo con una define quanto vasottratto ad ogni numero per ottenere la lettera (di base 1)

Non credo sia meno dispendioo, anzi, trasfersico dati nella memoria variabili, ma é mooooolto più espandibile e rapido da scrivere

si, ho capito.

Sai dove è il problema. Ora che ci penso, ad un 14 che corrisponde la lettera P, non saprei come ricavarlo, perchè , affinchè sono numeri singoli è semplice, ma essenndo qui un numero composto da due cifre, non saprei cosa fare.
che faccio scrivo case (i due numeri esadecimali corrispondenti al 1 e il 4 per formare il 14)= P ?

inoltre, ce un modo pre far scorrere il cursore mentre introduco i numeri sul display, cosi da avere una sequenza di numeri.

infine quella funzione che mi hai detto, non la conosco, cosa fa?

silente, non ho capito bene quello che vuoi fare , puoi spiegarmelo meglio perfavore?

torn24:
Ti dico che il progetto non ha niente a che fare con la macchina enigma, un nome ad effetto ma poi se trovi qualcuno all'esame che ha una minima idea di cosa sia una macchina enigma "basta solo pensare che ci sono voluti le migliori menti per poterla decifrare". Visto che ha fatto fatica Turing a capirci qualcosa, mi sembra alquanto pretenzioso che un maturando possa conoscerla al punto di replicarla :slight_smile:

torn24 Ti sbagli di grosso.
La macchina Enigma é semplice nella costruzione. Ha qualche errore che diminuisce le possibilitá di variazione e percui aumenta la vulnerabilitá. Il problema percui i messaggi sono stati decriptati dai inglesi é che la condizione di partenza (posizione dei 4 rulli e disposizione dei cavi sul panello cavi) sono definiti tramite un libro giorno per giorno.

Se i tedeschi avessero semplicemente aggiunti 2 rulli o avrebbero sostituito i rulli una volta all'anno gli inglesi non la avrebbero decifrata.

Un sistema valido di criptatura non si basa sulla segretezza del alogaritmo o sulla meccanica della macchina ma sulla sicurezza del alogaritmo anche pubblico e della chiave segreta con cui viene criptato il messaggio.

Ciao Uwe

@ stefno
Forse meglio che non chiami il Tuo progetto "Enigma" perché il nome fa troppo riferimento alla macchina di criptatura usata dai tedeschi nella 2 guerra mondiale.
Ciao Uwe

Se ho capito bene quello che va fatto è un sistema che riceve come input dei numeri (o meglio delle cifre con cui poi comporrà numeri) in base al numero ricevuto mostrerà una lettera (ce poi comporrà parole). Il problema sembra essere come associare un numero ad una lettera. Per questo probema mi è venuta una soluzione, ma questa soluzione ha due condizioni:
1)il collegamento numero/lettera deve essere fisso (se 1=a 1= sempre a)
2)i numeri sono in sequenza (senza buchi) oppure esiste un carattere mai usato

Se tali condizioni sono rispettate allora si potrebbe scrivere un array di char così costituito: ogni punto dell'array contiene la char che il numero pari all'indice dell'array codifica (es. se 10=a, 1=b, 2=c allora l'array diventa

char traduttore [3]={'a', 'b', 'c'};

E così facendo non bisogna scrivere tutta la switch case (che per 26 lettere+10 numeri+i segni+... diventa lunga) Certamente così sto occupando memoria variabili preziosa, ma tradurre è un attimo, in quanto se si desidera tradurre il numero N basta ordinare la scrittura della char presente all'N esimo elemento dell'array

ciao uwe, io vorrei creare una macchina capace di criptare, come la macchina enigma,capace di criptare dei messaggi, molto semplicemente. perchè ricordatevi che come il messaggio veniva criptato da una macchina, veniva poi decriptato da un altra macchina avendo una specie di password con cui si poteva attivare la macchina, la chiave di decriptatura.

io nella mia tesina, volevo inserire un progetto fatto con l'arduino, perche porto come tema centrale l'avanzamento e l'utilizzo delle nuove tecnologie, quindi avevo pensato anche alla macchina enigma in storia, cosi da parlare sia del suo utilizzo che anche del contesto storico, come la seconda guerra mondiale

ora, io non sono molto esperto con l'arduino come potete esserlo voi, per questo vi chiedo aiuto per completare il codice.

sennò ho fatto anche altri progetti come un piccolo ventilatore che si accede quando si supera una determinata temperatura, che viene rilevata da un termo resistore e inoltre la temperatura è segnata sul display.

ora le altre materie sono collegate solo per il fatto dell'utilizzo delle nuove tecnologie, ma storia e matematica sono collegate direttamente alla macchina enigma, pure se in teoria riesco a collegarmi a loro anche tramite il fatto che la macchina enigma, era una macchina tecnologica molto all'avanguardia per il suo tempo.

ora, dopo che vi ho spiegato un po il mio punto di vista, spero che mi possiate aiutare a risolvere il codice.

silente, tu vuoi creare un array di char, tipo char [4] {a,b,c,d}, dove in base all'indice ci sono tot lettere, giusto
?
il mio problema è nella costruzione di numeri a piu cifre (ad es. 12) a cui corrisponde la dodicesima lettera dell'alfabeto.

inoltre io avevo pensato che se tipo io pigio 1 sul telecomando, l'arduino deve aspettare un altro segnale per dire vai avanti cosi da continuare ad andare avanti, tipo il tasto POWER (3-POWER-9-POWER-1-POWER-13-POWER=CIAO), cosi non si dovrebbero creare disguidi, visto che ad ogni numero è associata una lettera.

cosi sul display inserisco una sequenza di numeri, per dire che mi è stata mandata da un'altra macchina enigma (esempio banale), e lo decripto, visto che io ho la password per sbloccare la macchina e che è in grado di decriptarlo.

... non è che sia un progetto nuovissimo comunque ... QUI hai una bella implementazione della vera macchina Enigma, fatta con un Arduno UNO (trovi schemi, codice sorgente, ecc. ecc).

E comunque, facendo una piccola ricerca con "arduino enigma machine simulator" escono appena ... 131'000 risultati da cui prendere spunto ... ::slight_smile:

Guglielmo

Guglielmo, ti giuro che io ho cercato ma non sono mai riuscito a trovare nulla, cosi ho dovuto ha sviluppare il codice da solo.
inoltre non ho molti pezzi, quindi dovevo creare un codice che potesse funzionare con le componenti che io ho. per questo utilizzo un telecomando.