Domanda Risolvere cifrario con analisi frequenze

Stato
Discussione chiusa ad ulteriori risposte.

CaffeLatte

Utente Electrum
17 Gennaio 2013
263
53
26
170
Ciao a tutti!
Premetto che sono nuovo in questo ambito, programmo in java da quasi un anno, a scuola(ITIS).
Qualche giorno fa decisi di creare un programma che riesca a decifrare un semplice algoritmo di cifratura a sostituzione, ma ho molti problemi:
-non riesco a far funzionare l'algoritmo che crea due array , uno di caratteri(tutti diversi) e uno delle percentuali.
Codice:
public void creaArrayDiCaratteriAndSimboli(){
        int ricorrenza=0;
        int l = 0;
        boolean match=false;
        for (int i = 0; i < messaggio.length(); i++) {
            for (int j = 0; j < caratteri.length; j++) {
                if (caratteri[j]==messaggio.charAt(i)) {
                    match=true;
                    ricorrenza++;
                }
            }
           
            if (match=false){
                caratteri[l]=messaggio.charAt(i);
                percentuale[l]= ricorrenza*100/messaggio.length();
                l++;
            }           
        }
        for (int i = 0; i < caratteri.length; i++) {
            System.out.println(caratteri[i]);
           
        }
    }
-l'algortimo di sostituzione dei caratteri nel messaggio mi pare sbagliato

Codice:
public void decodificaMessaggio(){
        for (int i = 0; i < messaggio.length(); i++) {
            for (int j = 0; j < caratteri.length; j++) {
                if (messaggio.toCharArray()[i]==caratteri[j]){

            switch(j){
                case 0:
                    messaggio.toCharArray()[i]='E';
                    break;
                case 1:
                    messaggio.toCharArray()[i]='A';
                    break;
                case 2:
                    messaggio.toCharArray()[i]='I';
                    break;   
                case 3:
                    messaggio.toCharArray()[i]='O';
                    break;
                case 4:
                    messaggio.toCharArray()[i]='N';
                    break;
                case 5:
                    messaggio.toCharArray()[i]='L';
                    break;  
                case 6:
                    messaggio.toCharArray()[i]='R';
                    break;
                case 7:
                    messaggio.toCharArray()[i]='T';
                    break;
                case 8:
                    messaggio.toCharArray()[i]='S';
                    break;
                case 9:
                    messaggio.toCharArray()[i]='C';
                    break;  
                case 10:
                    messaggio.toCharArray()[i]='D';
                    break;
                case 11:
                    messaggio.toCharArray()[i]='P';
                    break;  
                case 12:
                    messaggio.toCharArray()[i]='U';
                    break;      
                case 13:
                    messaggio.toCharArray()[i]='M';
                    break;  
                case 14:
                    messaggio.toCharArray()[i]='V';
                    break;      
                case 15:
                    messaggio.toCharArray()[i]='G';
                    break;      
                case 16:
                    messaggio.toCharArray()[i]='H';
                    break;
                case 17:
                    messaggio.toCharArray()[i]='F';
                    break;  
                case 18:
                    messaggio.toCharArray()[i]='B';
                    break;  
                case 19:
                    messaggio.toCharArray()[i]='Q';
                    break;  
                case 20:
                    messaggio.toCharArray()[i]='Z';
                    break;
               
            }
                }
            }
           
        }
       
    }

So perfettamente che il codice decifrato non sarà mai esattamente uguale all'originale, ma penso che aggiungerò altri algoritmi per facilitare la decifratura ecc...
Questo è il link dell' algoritmo intero.
 
Ultima modifica:
Andiamo con ordine

Nel primo codice tu per ogni lettera aggiorni la ricorrenza una volta sola, ovvero la prima volta che incontri tale carattere, e quindi ti ritroverai la percentuale sempre pari a 0. Un modo per risolvere tale inconveniente è rinunciare all'array delle percentuali per uno delle ricorrenze, e quindi calcolarti la percentuale in un secondo momento

Java:
int[] ricorrenze=new int[26];//NOTA: vanno inizializzati a 0
...
public void creaArrayDiCaratteriAndSimboli(){
int l=0;
for(int i=0; i<messaggio.lenght(); i++){
  char c=messaggio.charAt(i);
  boolean match=false;
  for(int j=0; j<l; j++){
   if(caratteri[j]==c){
    match=true;
    ricorrenze[j]++;
    break;
   }
  }
  if(!match){
   caratteri[l]=c;
   ricorrenza[l]=1;
   l++;
  }
}
...
}
tale algoritmo si potrebbe migliorare molto.

Per la seconda parte noto subito il metodo toCharArray(): tale metodo fornisce un array di vettori che è una copia della stringa, ovvero non modifichi la stringa originale. Inoltre ogni volta che invochi tale metodo viene allocato un array diverso
 
Innanzitutto grazie mille per la risposta!
Ho un piccolo problema con le ricorrenze: ho provato a fare un print dei valori ed è uscito questo insieme di simboli [I@2a139a55
 
Innanzitutto grazie mille per la risposta!
Ho un piccolo problema con le ricorrenze: ho provato a fare un print dei valori ed è uscito questo insieme di simboli [I@2a139a55
Questo perché hai passato a print l'array, e quindi ha stampato l'identificativo dell'array. Prova con:

Java:
for(int i=0; i<ricorrenze.lenght; i++)
 System.out.println(ricorrenze[i]);
 
Grazie mille, non so perchè abbia fatto quell'errore....
Ho un altro problema con la decodifica:
Codice:
public void decodificaMessaggio(){
        for (int i = 0; i <caratteri.length ; i++) {
            for (int j = 0; j <messaggio.length() ; j++) {
                if (messaggio.charAt(j)==caratteri[i]){
                    char c = messaggio.charAt(j);
            switch(i){
                case 0:
                    c='E';
                    break;
                case 1:
                    c='A';
                    break;
                case 2:
                    c='I';
                    break;   
                case 3:
                    c='O';
                    break;
                case 4:
                    c='N';
                    break;
                case 5:
                    c='L';
                    break;  
                case 6:
                   c='R';
                    break;
                case 7:
                   c='T';
                    break;
                case 8:
                    c='S';
                    break;
                case 9:
                    c='C';
                    break;  
                case 10:
                    c='D';
                    break;
                case 11:
                    c='P';
                    break;  
                case 12:
                    c='U';
                    break;      
                case 13:
                    c='M';
                    break;  
                case 14:
                    c='V';
                    break;      
                case 15:
                    c='G';
                    break;      
                case 16:
                    c='H';
                    break;
                case 17:
                    c='F';
                    break;  
                case 18:
                    c='B';
                    break;  
                case 19:
                    c='Q';
                    break;  
                case 20:
                    c='Z';
                    break;
               
            }
             messaggio.replace(messaggio.charAt(j), c);
                }
            }
           
        }
       
    }
continua a restituire il messaggio originale.
C'è un modo per togliere lo switch e renderlo più veloce?
 
In Java gli oggetti String sono oggetti costanti, ovvero non possono essere modificate in alcun modo, e quindi tutti i metodi che modificherebbero una stringa in realtà creano una nuova stringa, mentre la stringa originale rimane invariata.
Detto ciò, il metodo replace() ritorna una stringa, che è quella che ti interessa.

Per quanto riguarda lo switch prova con un array
Java:
char[] exc=new char[]{'E', 'A', 'I', ...}
...
c=exc[i];
 
Stato
Discussione chiusa ad ulteriori risposte.