Pues aqui un ejercicio que me tomaron en una calificada de Progra (no se donde diablos el profe saco este problema), muy tedioso, ya lo he solucionado, pero quisiera saber si alguno de ustds podria hacerlo de una manera diferente o en todo caso mas eficiente, en fin como para que practiques.
PRACTICA CALIFICADA DE PROGRAMACION
La situacion del ejercito aliado es desesperada.El ejercito de Adolf Hitler amenza con adueñarse definitivamente de Europa y comenzar su expansion por el mundo.Sus comunicaciones, ademas, estan cifradas con una poderosa máquina llamada ENIMGMA, que desafia toda intercepcepcion.
En BletChley Par, las mentes más poderosas del mundo libre se han reunido en secreto para tratar de encontrar la forma de romper los codigos alemanes.Han conseguido comprender el funcionamiento de ENIGMA, pero no resulta viable descifrar los mensajes manualmente.Para dificultar las cosas los mensajes alemanes originales estan escritor en español.
En un proyecto ultrasecreto, un grupo de fisicos aliados consiguen secuestrar a un programador español del siglo XXI con su máquina de computo (o sea tú). Su única esperanza es que este individuo los ayude a descifrar los mensajes alemantes, antes de que sea demasiado tarde...
Los mensajes alemanes utilizan el juego de 29 carácteres siguientes, codificados a partir de 0(los tres últimos son el espacio, el punto y la coma).
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 . ,
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
La máquina enigma tiene ruedas con esta secuencia de caracteres igual que el cuentakilometros de un auto,tiene ruedas con los digitos del 0 al 9. Si una rueda esta en la posicion A y se avanza 1, pasara a B; si avanza 29 pasos, volvera a la posicion A.
Tras traducirlo al español, lo primero que hacen los alemanes para codificar un mensaje es elegir una secuencia especial de 5 letras, que hara de semilla.Colocan esta secuencia al principio y el mensaje inmediatamente a continuacion.
EJEMPLO:
Supongase el mensaje
MATAR A LOS HUMANOSPara codificarlos, Enigma podia enteponder una semilla cualquiera, por ejemplo
RUDER preparando el mensaje asi:
RUDERMATAR A LOS HUMANOSSe multiplican y suman los codigos de RUDER (que son 17,20,3,4,17); por tanto tenemeros:
(17x20x3x4x17 + 17+20+3+4+17), y ese (69421 en este caso) es el numero de pasos que avanzará la rueda de la M. Eso nos lleva a la H. Por tanto, el mensaje pasa a ser:
RUDERHATAR A LOS HUMANOSLa misma operacion se haria para la A, con los codigos de las letras
UDERH. Y así sucesivamente. Eso nos llevaría al mensaje codificado:
RUDERHRML.EMG,AKYRMRNGNUHay que realizar un programa que lea cadenas de textos y los alamcene en un vector(siempre limitando a los caracteres mencionados arriba)con un mensaje codificado, y grabe en otro vector dichos mensajes codificados.EL programa tendra que realizar los cáclculos segun la "codificacion alemana".
Y aqui mi solucion:
/**
* @(#)codificados.java
*
* @author JEANS AZULF RUIZ
* @version 1.00 2007/6/8
*/
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
char Arreglo[]=new char[29];
public codificados() {
label
=new JLabel("Ingrese aqui Texo Codificado");
texto.addKeyListener(new ValidaNumero() );
area.setEditable(false);
area.setToolTipText("Esta ***** no se Edita");
area2.setEditable(false);
area2.setToolTipText("Esta ***** no se Edita");
b_deco
=new JButton("Decodificalo!!!");
panel.add(label);
panel.add(texto);
sub_panel.
setBorder(BorderFactory.
createTitledBorder("Textos Codificados... :"));
sub_panel2.
setBorder(BorderFactory.
createTitledBorder("Textos Decodificados... :"));
panel2.add(sub_panel);
panel2.add(sub_panel2);
b_deco.addActionListener(this);
iniciar();
setTitle(".::CODIFICADOS::.");
setSize(450,300);
setLocation(300,300);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
if(b_deco==e.getSource()){
if( texto.
getText().
length()<=5 ) JOptionPane.
showMessageDialog(this,
"Por favor ingrese Texto a decodificar VALIDO.\nRecuerde que el texto debe tener mas de 5 caracteres",
"Title",
JOptionPane.
INFORMATION_MESSAGE); else decodificar();
}
}
public void iniciar(){
for (int i = 0; i<26; i++)
Arreglo[ i ]=(char)(i+65) ;
Arreglo[26]=(char)(32) ;
Arreglo[27]=(char)(46) ;
Arreglo[28]=(char)(44) ;
}
public int buscar(char car){
for(int i=0;i<Arreglo.length;i++ )
if( Arreglo[ i ]==car ) return i;
return (-1);
}
public void decodificar(){
//Creo mi arreglo con la longitud del texto menos los 05 caractereres que son los que han servido de semilla
char arreglo[]=new char[ ( texto.getText().length() ) -5 ];
//agrego al vector
codi.addElement( texto.getText().toUpperCase() );
String N
=texto.
getText().
toUpperCase(); int tope= N.length()-5;
for(int i=0;i<tope;i++){
//formo la subcadena que contiene los numeros antecesores
String n
= N.
substring(tope
-i
-1 , tope
+5-i
-1);
//multiplico los digitos
int Pro=1;
int Sum=0;
for(int j=0;j<n.length();j++ ){
Pro*= buscar(n.charAt(j));
Sum+= buscar(n.charAt(j));
}
Pro+=Sum;
//obtengo el residuo
Pro=(Pro%29);
int t=0,k=0;
int resi= buscar( N.charAt(N.length()-1-i ) );
do{
t= (29*k)+ resi;
k++;
}while(Pro>t);
arreglo[arreglo.length-i-1]= Arreglo[t-Pro];
}
//agrego al otro vector
deco.addElement(s_deco);
for(int h=0;h<deco.size();h++ ){
s_codi
+=(String)codi.
elementAt(h
); s_decodi
+= (String)deco.
elementAt(h
); s_codi+="\n";
s_decodi+="\n";
}
area.setText(s_codi);
area2.setText(s_decodi);
texto.setText("");
}
//clase para que la caja de texto solo acepte LETRAS
char c = e.getKeyChar();
getToolkit().beep();
e.consume();
}
if( texto.
getText().
length()<=5 ) JOptionPane.
showMessageDialog(null,
"Por favor ingrese Texto a decodificar VALIDO.\nRecuerde que el texto debe tener mas de 5 caracteres",
"Title",
JOptionPane.
INFORMATION_MESSAGE); else decodificar();
}
}
}
public static void main
(String[] args
) { new codificados();
}
}
Y aparte de decodificar los mensajes, para verificiar que estaba en lo correcto, tuve que hacer otra aplicacion en la cual me codificara los mensajes, que es esta:
/**
* @(#)decodificados.java
*
* @author JEANS AZULF RUIZ
* @version 1.00 2007/6/8
*
* APLICACION EN JAVA QUE ME VA A CODIFICAR MENSAJES,PARA LUEGO UTILIZARLOS EN LA OTRA APLICACION
*/
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
char Arreglo[]=new char[29];
public decodificados() {
crea_objetos();
agrega_objetos();
listar_objetos();
propiedades_ventana();
}
public void crea_objetos(){
label
=new JLabel("Ingrese aqui Texo A codificar");
area.setEditable(false);
area.setToolTipText("Esta ***** no se Edita");
area2.setEditable(false);
area2.setToolTipText("Esta ***** no se Edita");
b_deco
=new JButton("Codificalo!!!"); }
public void agrega_objetos(){
panel.add(label);
panel.add(texto);
sub_panel.
setBorder(BorderFactory.
createTitledBorder("Textos Sin Codificar... :"));
sub_panel2.
setBorder(BorderFactory.
createTitledBorder("Textos Codificados... :"));
panel2.add(sub_panel);
panel2.add(sub_panel2);
}
public void listar_objetos(){
b_deco.addActionListener(this);
texto.addKeyListener(new ValidaNumero() );
iniciar();
}
public void propiedades_ventana(){
setTitle(".::DECODIFICADOS::.");
setSize(450,300);
setLocation(300,300);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
if(b_deco==e.getSource()){
if(texto.
getText().
length()<=5) JOptionPane.
showMessageDialog(this,
"Por favor ingrese datos validos"); else codificar();
}
}
//METODO QUE ME PERMITE CODIFICAR LAS CADENAS
public void codificar(){
String semilla
=crea_semilla
(); String cadena
= ( texto.
getText() ).
toUpperCase(); int limite=cadena.length() ;
cadena= semilla.concat(cadena);
for(int i=0;i<limite;i++){
String sub
= cadena_codificada.
substring(i,i
+5); int suma=0,produc=1;
for(int j=0;j<5;j++){
suma+= buscar(sub.charAt(j) );
produc*= buscar(sub.charAt(j) );
}
suma+=produc;
suma%=29;
int tempo= suma+ buscar(cadena.charAt(i+5));
int resul=tempo%29;
cadena_codificada
+=String.
valueOf(Arreglo
[resul
]); }
area.append( (texto.getText()).toUpperCase() +"\n" );
area2.append(cadena_codificada +"\n" );
texto.setText("");
}
public void iniciar(){
for (int i = 0; i<26; i++)
Arreglo[ i ]=(char)(i+65) ;
Arreglo[26]=(char)(32) ;
Arreglo[27]=(char)(46) ;
Arreglo[28]=(char)(44) ;
}
public int buscar(char car){
for(int i=0;i<Arreglo.length;i++ )
if( Arreglo[ i ]==car ) return i;
return (-1);
}
//clase para que la caja de texto solo acepte LETRAS
char c = e.getKeyChar();
getToolkit().beep();
e.consume();
}
if(texto.
getText().
length()<=5) JOptionPane.
showMessageDialog(null,
"Por favor ingrese datos validos"); else codificar();
}
}
}
/* A ----> 65
* Z ----> 90
* ESTE METODO CREA UNA SEMILLA AL AZAR DE CINCO CARACTERES PARA UN TEXTO QUE SE VA A CODIFICAR*/
int temporal=0;
int k=0;
do{
temporal
=(int)(Math.
random()*91); if(temporal>=65 && temporal <=90){
//char tmp= (char)temporal;
cadena
+=String.
valueOf( (char)temporal
); k++;
}
}
while(k!=5);
return cadena;
}
// EL MAIN
public static void main
(String[] args
) { new decodificados();
}
}
Pd: me falto validar para cuando el usuario ingrese caracteres como : " "" ! · $ % & / () = ? ¿ etc."
Si crees que ya lo haz terminado, puedes probar con estos codigos, o en todo caso codicarlos con la segunda aplicacion, esa que se llama decodificados
MATAR A LOS HUMANOS WCNBIXRAU. DPVFHF.ON,GYY
ENCONTRAR EL TESORO JRHOAWPCJD UKJSIQKDOFWQP
APAGA EL COMPUTADOR WJVASMRKFFG.WQMOG,FDORUU
QUITATE LAS MEDIAS NTJSE THR.WYAOAU OUZEPC
ROMPE LA VENTANA VGVYWIYB,KERSOZH,EWLY
Saludos
Azulf