PDA

View Full Version : [Java] Cifratore rot13 di frasi e programmazione object oriented


frizzo28
07-08-2007, 16:16
Ciao a tutti ho scritto in java questo programma che consente di cifrare e decifrare frasi codificate in rot13.FUNZiona perfettamente ma essendo uno dei miei primi programmi object oriented volevo chiedervi se come 'filosofia' orientata agli oggetti ci siamo o se ho fatto i classici errori di chi e' abituato alla programmazione lineare?

import java.lang.*;
import java.io.*;
import java.util.*;

class Codificatore
{

private char co[] = new char[130];
private char decrittati[] = {'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'};
private char rot13[] = {'n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m'};
private int n=0;
private int tipo=0;


//Serve per inserire codifica rot13
public void setRot13(char codice[],int n){co=codice;tipo=1;this.n=n;}

//Questo serve per inserire testo non codificato
public void setSprotetto(char codice[],int n){co=codice;tipo=2;this.n=n;}


//Metodo per convertire se e' stato inserito codice rot13 lo decritta e se e' stato inserito testo
//in chiaro lo cripta in rot13
public void converti()

{
int i,j,tr;

if(tipo==1)
{
//Da rot13 a decrittato

for(i=0;i<n;i++)
{
j=0;
tr=0;
while(j<26&&tr==0){if(co[i]==decrittati[j]){co[i]=rot13[j];tr=1;}j++;}
}

tipo=2;
}

else if(tipo==2)
{
//Da dcrittato a rot13

for(i=0;i<n;i++)
{
j=0;
tr=0;
while(j<26&&tr==0){if(co[i]==rot13[j]){co[i]=decrittati[j];tr=1;}j++;}


}

tipo=1;
}


}

//Questo metodo serve per stampare a video il testo
public void stam()
{
int i;
for(i=0;i<n;i++)
System.out.print(""+co[i]);
}




}


class ProgCodificaore
{

public static void main(String argv[])
{

int n=0,i;
char codice[] = new char[130];
String cletto = new String();
String scelta = new String();

InputStreamReader input = new InputStreamReader(System.in);
BufferedReader Tastiera = new BufferedReader(input);

//Chiedo che codice si vuol inserire
System.out.print("\nProgramma per convertire da rot13 a decrittato e viceversa\nIl codice che sto per inserire e' in:\n1. Rot13 \n2.In chiaro\n Scelta: ");

//Leggo la scelta
try
{
scelta=Tastiera.readLine();
}
catch(IOException e){}

System.out.println("Immetti testo: ");
//Aquisisco testo
try
{
cletto=Tastiera.readLine();
}
catch(IOException e){}

//Salvo in n la lunghezza del testo inserito
n=cletto.length();

//Trasformo la scringa in un array di caratteri cosi' e' piu' comoda da maneggiare
for(i=0;i<n;i++)
{
codice[i] = cletto.charAt(i);
}

//Creo un oggetto appartenente alla classe Codificatore da me creata
Codificatore gg= new Codificatore();

//Qui in base alla scelta dico all'oggetto se sto inserendo testo in chiaro o crittato con rot13
if(scelta.charAt(0)=='1')gg.setRot13(codice,n);
else if(scelta.charAt(0)=='2')gg.setSprotetto(codice,n);

//Chiamo il metodo per convertire e per stampare
gg.converti();
System.out.println("\nConvertito: ");
gg.stam();

//Qui per prova riconverto tutto al formato originario
System.out.println("\nRiconvertito: ");
gg.converti();
gg.stam();
System.out.println("");

}

}

grazie ciao

PGI-Bis
07-08-2007, 16:39
La programmazione orientata agli oggetti non prevede la possibilità che si commettano errori, nel senso più comune del termine "hey, questo non è object oriented".

Il massimo che può capitare è che quello che scrivi non corrisponda a quello che hai immaginato.

Per verificare la corrispondenza puoi leggere il codice da un punto di vista OO e vedere cosa rappresenta. Se il modello di sistema (quello che hai scritto) risultante coincide con il sistema di riferimento (quello che avresti voluto scrivere) allora è tutto ok.

Se non c'è questa corrispondenza, il programma resta orientato agli oggetti ma essendo la rappresentazione di un sistema diverso da quello intenzionale il suo comportamento potrebbe essere diverso da ciò che ci si aspetterebbe.

Nel codice che hai incollato sono definiti due oggetti, Codificatore e Programma. La definizione di Programma dipende dalla definizione di Codificatore.

Poichè Java non consente di codificare precondizioni e postcondizioni di un contratto al di fuori del contratto stesso, la dipendenza che sussiste tra una definizione ed un'altra è in linea di principio completa.

Detto altrimenti, nel tuo programma la definizione di Codificatore è immutabile perchè se cambi qualche pezzo di Codificatore esiste la possibilità che Programma, il quale assume codificatore come parte di sè (per via di quel Codificatore gg= new Codificatore()) muti di riflesso.

L'esistenza di due oggetti, Codificatore e Programma e la dipendenza che esiste tra Programma e Convertitore (cioè l'impossibilità che Convertitore subisca modifiche che non si riflettano su Programma), coincide anche con il sistema che volevi rappresentare?

La risposta sta a te.

andbin
07-08-2007, 17:18
Non volevo dirlo :p ... ma l'algoritmo ROT13 è simmetrico, cioè è lo stesso per la codifica e decodifica.

È sufficiente fare:
public class ROT13
{
private ROT13 () { }

public static String translate (String input)
{
char[] buf = input.toCharArray ();

for (int i = 0; i < buf.length; i++)
{
if ((buf[i] >= 'A' && buf[i] <= 'M') || (buf[i] >= 'a' && buf[i] <= 'm'))
buf[i] += 13;
else if ((buf[i] >= 'N' && buf[i] <= 'Z') || (buf[i] >= 'n' && buf[i] <= 'z'))
buf[i] -= 13;
}

return new String (buf);
}
}

Mixmar
07-08-2007, 17:54
Edit

71104
07-08-2007, 17:58
Non volevo dirlo :p ... ma l'algoritmo ROT13 è simmetrico, cioè è lo stesso per la codifica e decodifica.

È sufficiente fare:
public class ROT13
{
private ROT13 () { }

public static String translate (String input)
{
char[] buf = input.toCharArray ();

for (int i = 0; i < buf.length; i++)
{
if ((buf[i] >= 'A' && buf[i] <= 'M') || (buf[i] >= 'a' && buf[i] <= 'm'))
buf[i] += 13;
else if ((buf[i] >= 'N' && buf[i] <= 'Z') || (buf[i] >= 'n' && buf[i] <= 'z'))
buf[i] -= 13;
}

return new String (buf);
}
}

adesso con quello che dirò io PGI-Bis mi scannerà :asd:
ma volendolo portare in un'ottica maggiormente OO si potrebbe derivare una classe ROT13String da String. partendo dal codice di andbin si potrebbe eliminare il costruttore privato e il parametro del metodo, il quale lavorerebbe su this.

altra soluzione leggermente differente: partendo dall'assunto che la RAM sia un canale sicuro e che i canali di memorizzazione/comunicazione non sicuri siano tutti quelli accessibili tramite la serializzazione, si potrebbero reimplementare l'interfaccia Serializable e i metodi readObject e writeObject per fare in modo che la stringa sia scritta in chiaro in memoria e si cripti/decripti automaticamente quando viene serializzata.

era solo qualche idea. :)

frizzo28
07-08-2007, 18:10
Grazie a tutti per le soluzioni :) ora faccio un po di prove... anche se di quello suggerito da 71104 come "altra soluzione leggermente differente:" non ci ho capito molto:confused:

ciao

PGI-Bis
07-08-2007, 18:31
ma volendolo portare in un'ottica maggiormente OO

Non è un'ottica "maggiormento" OO ( :batte il pugno sul tavolo: ). E' un diverso sistema di riferimento.

E' un sistema in cui esistono delle "frasi ROT13".

Ci sono anche in quello di frizzo28. Frizzo ha rappresentato le sue frasi con "char[]".

E' giusto o sbagliato in sè? Ma certamente no. E' o non è corrispondente al sistema da realizzare.

L'oggetto "frase" definito dal codice di frizzo è "una sequenza di caratteri".

Se "una sequenza di caratteri" coincide anche con la sua definizione di "frase rot13" allora char[] ha una corrispondenza con il sistema di riferimento.

E questo è tutto quello che si può motivatamente dire.

Mixmar
07-08-2007, 20:20
Non è un'ottica "maggiormento" OO ( :batte il pugno sul tavolo: ). E' un diverso sistema di riferimento.

E' un sistema in cui esistono delle "frasi ROT13".

Ci sono anche in quello di frizzo28. Frizzo ha rappresentato le sue frasi con "char[]".

E' giusto o sbagliato in sè? Ma certamente no. E' o non è corrispondente al sistema da realizzare.

L'oggetto "frase" definito dal codice di frizzo è "una sequenza di caratteri".

Se "una sequenza di caratteri" coincide anche con la sua definizione di "frase rot13" allora char[] ha una corrispondenza con il sistema di riferimento.

E questo è tutto quello che si può motivatamente dire.

Capisco (o almeno, credo di capire) la tua obbiezione. Si può dire però che la soluzione di andbin, così come quella di 71104, se non più "OO", siano però "stilisticamente più curata", dove per stile si può intendere la capacità di aderire più o meno profondamente al "modus operandi" di un linguaggio di programmazione, intesa in ultima sintesi come "capacità di sfruttare quanto più possibile i costrutti offerti per rendere semplice e/o elegante" il codice stesso?

E' una domanda sincera, assolutamente non polemica, che nasce da una riflessione, chiaramente non mia ma "sublimata" da altre fonti: che il codice maggiormente "elegante" fosse (per una qualche virtù euristica) anche il più pulito, il più semplice da manutenere/aggiornare/riscrivere. Come se l'estetica portasse necessariamente ad un risultato superiore, non tanto per funzionalità (che, come hai detto tu, è uguale), quanto per in base ad altri criteri di valutazione del prodotto/programma.

Oltre ad avere ovviamente un premio in se stessa, come la poesia: un codice scritto in maniera "accattivante" è più bello da leggere, ça va sans dire... :D

PGI-Bis
07-08-2007, 20:37
Se dovessi farmi guidare dai sentimenti anche io dire "sì, preferirei una soluzione che individui un oggetto FraseROT13".

Ma qui la domanda non è se piaccia o non piaccia ciò che è stato scritto. Era "questo è orientato agli oggetti"?

Poichè la risposta non può che essere sì, il problema per me è diventato: ciò che è scritto da un punto di vista orientato agli oggetti corrisponde anche a quello che avrei voluto scrivere?

In termini astratti parlare di eleganza, semplicità, cura eccetera può non essere sbagliato. Occorre tuttavia avere una definizione quantitativa di eleganza, semplicità, cura. Vale a dire una definizione che, applicata al codice, mi permetta di dire:

Questo è elegante, questo non è elegante oppure questo è 25 volte elegante.

Esiste una definizione di eleganza di questo genere? Se esiste, allora l'eleganza è una metrica del software. Se non esiste, allora l'eleganza conta quando un due di bastoni con briscola a denari.