[C++] Vigenere con alfabeto italiano

di il
2 risposte

[C++] Vigenere con alfabeto italiano

Ho creato un programma che esegue la cifratura di un testo con il cifrario di vigenere. durante la compilazione non mi da problemi, ma al momento dell'esecuzione riesco solo ad inserire la chiave e dopo mi compare il seguente messaggio d'errore: "This application has requested the Runtime to terminate it in an unusual way".

qui c'è l'implementazione della classe

#include "vigenere.h"
#include <string>
using namespace std;

//genera la chiave
Vigenere::Vigenere(string str){
                       key = str;
                       key = StringToUpper(key);
                       for(int cnt = 0; cnt < key.length(); cnt++){
                               if(key[cnt] < 'A' || key[cnt] > 'Z')
                               key.erase(cnt,1);
                       }
                       
                       //nel caso in cui la chiave sia più corta del testo
                       for(int cnt = 0; cnt < key.length(); cnt++){
                               if(key[cnt] >= 'A' && key[cnt] <= 'Z')
                                      key += key[cnt];                                                               
                       }
                                                                      
                       return;
}

char Vigenere::ALPH[21] = {'A','B','C','D','E','F','G','H','I','L','M','N','O','P','Q','R','S','T','U','V','Z'};                   

//tavola di Vigenere con alfabeto italiano
char Vigenere::Table(char alph[21]){
                       //char alfabeto[21]= {'A','B','C','D','E','F','G','H','I','L','M','N','O','P','Q','R','S','T','U','V','Z'};
                       for(int i = 0; i < 21; i++){
                               alph[i] = ALPH[i];
                               }
                        
                       int ROWS(21);
                       int COLS(21);
                                              
	                   for(int i = 0; i < ROWS; i++){		                       
		                           for(int j = 0; j < COLS; j++){
			                       VIG[i][j]=alph[(i + j)%21];
			                       }
                        }
                        return VIG[ROWS][COLS];
}

string Vigenere::StringToUpper(string convstr){
       for(int cnt = 0; cnt < convstr.length(); cnt++){
               convstr[cnt] = toupper(convstr[cnt]);
               }
       return convstr;
}

//elimina i caratteri speciali, tenendo solo le lettere
string Vigenere::EraseChar(string str){
       for (int i = 0; i < str.length(); i++){
           if(!(str[i] >= 'A' && str[i] <= 'Z'))
                       str.erase(i,1);
                       i--;
                       }
       return str;
}   

string Vigenere::encode(string text){
       string line;
                     
       //cerca il valore corrispondente alla chiave nella prima colonna di VIG
       int index_k;
       for(int i = 0; i < 21; i++){ 
               if(key[i]==VIG[i][1])
               index_k = i;
       }
       
       //cerca il valore corrispondente al testo nella prima riga di VIG
       int index_t;
       for(int i = 0; i < 21; i++){
               if(text[i]==VIG[1][i])
               index_t = i;
       }
       
       //calcola la lettera codificata
       for(int i = 0; i < text.length(); i++){
               line[i] = ALPH[(index_k + index_t)%21];
       }
       
       line = StringToUpper(line); 
       if(!line.empty()){
           line = EraseChar(line);
           }
           
       return line;
}

string Vigenere::decode(string text){
       string line;
              
       //cerca il valore corrispondente alla chiave nella prima colonna di VIG
       int index_key;
       for(int i = 0; i < 21; i++){
               if(key[i]==VIG[i][1])
               index_key = i;
       }
       
       //nella riga i-esima cerca la lettera corrispondente al carattere cifrato
       int index_d;
       for(int i = 0; i < 21; i++){
               if(text[i] == VIG[index_key][i])
               index_d = i;
       }
       
       //calcola la lettera decodificata
       for(int i = 0; i < text.length(); i++){
               line[i] = ALPH[index_d];
       }
       
       line = StringToUpper(line);
       if(!line.empty()){
           line = EraseChar(line);
           }
           
       return line;
}
e il main

#include <cstdlib>
#include <iostream>
#include <string>
#include "vigenere.h"
using namespace std;

int main()
{
    string chiave;
    cout<<"Inserire la chiave:\n";
    cin>>chiave;
    Vigenere cipher(chiave);
    
    char alfabeto[21];
    for(int i = 0; i < 21; i++){
            alfabeto[i] = 'V';
            }
            
    cipher.Table(alfabeto);
    
    string original;
    cout<<"Inserire il testo:\n";
    cin>>original;
    
    string encrypted = cipher.encode(original);
    string decrypted = cipher.decode(encrypted);
    
    cout<<original<<endl;
    cout<<"Testo crittografato: "<<encrypted<<endl;
    cout<<"Testo decrittografato: "<<decrypted<<endl;
    
    getchar();
            
}

credo che il problema sia la funzione che genere una chiave lunga quanto il testo da criptare.
help

2 Risposte

  • Re: [C++] Vigenere con alfabeto italiano

    
    for(int cnt = 0; cnt < key.length(); cnt++){
                                   if(key[cnt] < 'A' || key[cnt] > 'Z')
                                   key.erase(cnt,1);
                           }
    
    cosa succede quando cancelli un elemento da una stringa? Succede che i suoi iteratori non sono + validi.
    Soluzione?
    usare remove_if del header <algorithm>
  • Re: [C++] Vigenere con alfabeto italiano

    Ho risolto il problema della generazione della chiave. funziona quasi tutto il programma tranne la funzione encode
    
    string encode(string text){
           string line;    
           char ALPH[21] = {'A','B','C','D','E','F','G','H','I','L','M','N','O','P','Q','R','S','T','U','V','Z'};
           text = StringToUpper(text); 
           if(!text.empty()){
               text = EraseChar(text);
           }
           
           cout << "String text: " << text << endl;
                  
           int index_k[key.length()];  //array degli indici della chiave           
           for(int i = 0; i < key.length(); i++){
                   for(int j = 0; j < 21; j++){
                           if(key[i] == ALPH[j])
                           index_k[i] = j;
                   }
           cout << "Indice chiave " << i << ": " << index_k[i] << endl;                
           }
           
           int index_t[text.length()];  //array degli indici del testo
           for(int i = 0; i < text.length(); i++){
                   for(int j = 0; j < 21; j++){
                           if(text[i] == ALPH[j])
                           index_t[i] = j;
                   }
           cout << "Indice testo " << i << ": " << index_t[i] << endl;                
           }
                 
           //calcola la lettera codificata
           for(int i = 0; i < text.length(); i++){
                   line[i] = ALPH[(index_k[i%key.length()] + index_t[i])%21];
                   cout << "Lettera codificata " << i << ": " << line[i] << endl;
           }
           
           return line;       
        }
    
    quando la richiamo nella funzione main
    
    string testo;
        cout << "Inserire testo\n";
        cin >> testo;
        
        string cifrato = cipher.encode(testo);
        
        cout << "Testo codificato: " << cifrato << endl;
    
    non mi compare nulla in output. come posso fare per risolvere il problema?
Devi accedere o registrarti per scrivere nel forum
2 risposte