[ Foro de Pascal ]

Maquina enigma!

29-Apr-2011 19:58
Miguel Angel Perez Perez
7 Respuestas

hola buenas, la verdad esta pagina me esta viniendo bien pero aun sigo siendo un novato de la programacion a gran escala y necesitaria algo de ayuda con este proyecto que me piden

Escriba un programa en Free Pascal que simule el funcionamiento de la maquina Enigma para decodi
car el chero de texto encriptado que se proporciona junto a este enunciado.
El programa pedira al usuario introducir una posicion inicial valida para cada uno de los rotores de
la maquina1. Se pedira ademas el nombre del chero a decodi car (o codi car segun el caso2) hasta que
se haya introducido un nombre correcto (de un chero que exista en el disco duro). Tambien se pedira un
nombre para el chero donde se va a guardar el texto despues de haber sido procesado por la maquina.
Ese chero debera tener la extension \.txt".


*anexo

ha sido codi cado con una maquina Enigma de 2 rotores y un alfabeto de 28 caracteres, es decir que
cada uno de los 2 rotores tiene 28 posiciones, empezando con el caracter espacio hasta la letra 'Z':
' .ABCDEFGHIJKLMNOPQRSTUVWXYZ'
Tambien se ha ltrado informacion referente al cableado interno de cada rotor, es decir aquella con -
guracion que hace que cada rotor, al activarse una letra en su super cie, devuelva una posicion.
Con guracion rotor1
' .ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'EKMFLG DQVZNTOWY.HXUSPAIBRCJ'
Con guracion rotor2
' .ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'AJDKSIR.UXBLHWTMCQGZNP YFVOE'
Con guracion re
ector3
' .ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'.


01-May-2011 11:39
Nacho Cabanes (+32)

En primer lugar, se lee fatal. Supongo que le habrás pasado un OCR, porque se ha saltado todas las sílabas "fi": "Conguración", "chero"...

En segundo lugar... ¿cual es la duda? Porque no se trata de que nadie haga todo el trabajo por ti, sino de que te ayudemos con las dudas puntuales que tengas.


01-May-2011 16:58
Miguel Angel Perez Perez

La duda, es que no se por donde empezar a meterle mano al proyecto, y era por si alguien sabia darme una breve orientacion de como deberia empezar a elaborarlo.


02-May-2011 10:17
Nacho Cabanes (+32)

La idea básica es que tienes dos cadenas: una es el "texto claro" y otra son las equivalencias de cada letra:

' .ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'EKMFLG DQVZNTOWY.HXUSPAIBRCJ'

Cuando estás cifrando texto, para cada letra de texto claro, la deberás cambiar por la que está en la misma posición de la cadena de cifrado. Por ejemplo, HOLA se convertiría en:

V.OM

(en pantalla basta con mirar qué letra tiene debajo).

Para descifrar, realizas el mismo paso, pero usando las cadenas en orden contrario: miras en la cadena de cifrado para ver en qué posición está la letra, y buscas qué carácter hay en la misma posición del "texto claro".

Por ejemplo, si la cadena cifrada es GM, los pasos serían

- Buscar en qué posición de la cadena de cifrado aparece la G
- Aparece en la posición 6
- La traducción de esa letra será la que hay en la posición 6 del texto claro: D

- Buscar en qué posición de la cadena de cifrado aparece la M
- Aparece en la posición 3
- La traducción de esa letra será la que hay en la posición 6 del texto claro: A

Luego el "texto cifrado" GM equivale al "texto claro" DA.

Duro con ello y... ¡Suerte!


02-May-2011 22:54
D G

Veo que ni te has mirado el código, pero da igual, porque ya lo tengo terminado. Sólo era para afinar algunas cosas, y si podía hacer procedimientos y funciones para dejarlo más modular, pero funciona ya a la perfección. Te reenvío el código y gracias igualmente =D.
Saludos

program Enigma;
{$mode objfpc}
uses crt;
const Ini1='M';Ini2='D';                                                 {Configuración Inicial de los rotores }
var

  abierto_e,abierto_s:boolean;                                          {Estado de los ficheros Entrada.txt/Salida.txt}
  entrada,salida:Text;
  nombre_e,nombre_s:string;                                             {Nombre de los ficheros, debe incluir la ruta, ej: C:\..}

  vec:array[1..28] of char;                                             {Lista inicial}
  Rot1_out,Rot1_in,Rot2_out,Rot2_in,Refl_out,Refl_in,aux:string[28];    {Rotores INput y OUTput}
  i,n,u,m:integer;                                                      {Variables contadores, bucles, multiplo... }
  z:char;                                                               {La variable que almacena el caracter leído}
  multiplo:boolean;


begin
    writeln('Programa que lee un fichero Entrada.txt');
    writeln('Y lo descifra, reescribiendolo en uno Salida.txt');

  try
   writeln('Escriba el nombre del fichero a analizar,con su respectiva ruta');
   readln(nombre_e);
   assign(entrada, nombre_e);
   reset(entrada);
   abierto_e:=TRUE

  except
   writeln('ERROR! El fichero no existe');
   abierto_e:=false;
  end;

  try
   writeln('Escriba el nombre del fichero procesado');
   readln(nombre_s);
   assign(salida,nombre_s);
   rewrite(salida);                                        {Descifra y escribe en el fichero salida, a cada caracter}
   abierto_s:=TRUE;

  except
     writeln('Error! NO SE PUEDE ESCRIBIR el archivo de salida');
     abierto_s:=FALSE;
  end;

clrscr;

writeln('_____CONFIG. ROTORES : ',Ini1,',',Ini2,'_________________________');
writeln;

          {Config. inicial de Rotores (Internos y externos)}
    Rot1_in:=' .ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    Rot1_out:='EKMFLG DQVZNTOWY.HXUSPAIBRCJ';
    Rot2_in:=' .ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    Rot2_out:='AJDKSIR.UXBLHWTMCQGZNP YFVOE';
    Refl_in:=' .ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    Refl_out:='. YRUHQSLDPXNGOKMIEBFZCWVJAT';
    vec:=Rot1_in;

{Permutacion del 1ºRotor}
for i:=1 to length(Rot1_in) do

 if Rot1_in[i]=Ini1 then
  begin
   aux:=copy(Rot1_in,1,i-1);
   delete(Rot1_in,1,i-1);
   Rot1_in:=Rot1_in+aux;

   aux:=copy(Rot1_out,1,i-1);
   delete(Rot1_out,1,i-1);
   Rot1_out:=Rot1_out+aux;
  end;

{Permutacion del 2ºRotor}
for i:=1 to length(Rot2_in) do

 if Rot2_in[i]=Ini2 then
  begin
   aux:=copy(Rot2_in,1,i-1);
   delete(Rot2_in,1,i-1);
   Rot2_in:=Rot2_in+aux;

   aux:=copy(Rot2_out,1,i-1);
   delete(Rot2_out,1,i-1);
   Rot2_out:=Rot2_out+aux;
  end;

{Muestra Rotores permutados}

 writeln;                    {Vector Inicial}
 write('Vector inicial: [');
 textcolor(11);
 write(vec);
 textcolor(15);
 writeln(']');
 writeln;

 writeln;                   {1ºRotor IN}
 write('    Rotor 1 IN: [');
 textcolor(10);
 write(Rot1_in);
 textcolor(15);
 writeln(']');

 writeln;                   {1ºRotor OUT}
 write('   Rotor 1 OUT: [');
 textcolor(2);
 write(Rot1_out);
 textcolor(15);
 writeln(']');

 writeln;                   {2ºRotor IN}
 writeln;
 textcolor(15);
 write('    Rotor 2 IN: [');
 textcolor(9);
 write(Rot2_in);
 textcolor(15);
 writeln(']');

 writeln;                   {2ºRotor OUT}
 textcolor(15);
 write('   Rotor 2 OUT: [');
 textcolor(1);
 write(Rot2_out);
 textcolor(15);
 writeln(']');

 writeln;                    {Reflector IN}
 writeln;
 textcolor(15);
 write('  Reflector IN: [');
 textcolor(13);
 write(Refl_in);
 textcolor(15);
 writeln(']');

 writeln;                   {Reflector OUT}
 textcolor(15);
 write(' Reflector OUT: [');
 textcolor(5);
 write(Refl_out);
 textcolor(15);
 writeln(']');
 writeln;
 writeln('_______________________________________________');

writeln;
writeln;
writeln('Presione Enter Para continuar...');
    readln;
    clrscr;

u:=1;

REPEAT    {--------------------COMIENZO DE BUCLE--------------------}{Se repite a cada caracter que lee}
  begin
  read(entrada,z);

 {Puesto inicial}
 for i:=1 to length(vec) do
   if vec[i]=z then
    n:=i;

{Rotor 1 IN-OUT}
z:=Rot1_in[n];
for i:=1 to length(Rot1_out) do
 if Rot1_out[i]=z then
   n:=i;

{Rotor 2 IN-OUT}
z:=Rot2_in[n];
for i:=1 to length(Rot2_out) do
if Rot2_out[i]=z then
   n:=i;

{Reflector IN-OUT}
z:=Refl_in[n];
for i:=1 to length(Refl_out) do
if Refl_out[i]=z then
   n:=i;

{Rotor 2 OUT-IN}
z:=Rot2_out[n];
for i:=1 to length(Rot2_in) do
if Rot2_in[i]=z then
   n:=i;

{Rotor 1 OUT-IN}
z:=Rot1_out[n];
for i:=1 to length(Rot1_in) do
if Rot1_in[i]=z then
   n:=i;

{Puesto Final}
z:=vec[n];                  {b es la letra descifrada}
write(salida,z);
                    {u-1 es el numero de bucles o iteraciones realizadas, equivalente al nº de letras leidas de Entrada.txt}


                {Permutacion por cada caracter}
   aux:=copy(Rot1_in,1,1); {1ºRotor IN}
   delete(Rot1_in,1,1);
   Rot1_in:=Rot1_in+aux;

   aux:=copy(Rot1_out,1,1); {1ºRotor OUT}
   delete(Rot1_out,1,1);
   Rot1_out:=Rot1_out+aux;


    m:=u mod 28;            {Comprueba si es múltiplo de 28, en tal caso el 2º Rotor gira una posición}
    if m=0 then
    multiplo:=true
    else
    multiplo:=false;

    if multiplo=true then
     begin

    aux:=copy(Rot2_in,1,1);
   delete(Rot2_in,1,1);
   Rot2_in:=Rot2_in+aux;

   aux:=copy(Rot2_out,1,1);
   delete(Rot2_out,1,1);
   Rot2_out:=Rot2_out+aux;
     end;

u:=u+1;         {Avanza el contador de iteraciones}
end;
UNTIL EOF(entrada);  {Termina de leer el fichero Entrada.txt}

  {--------------------FIN DE BUCLE--------------------}


writeln(salida,' ');
writeln(salida,' ');
writeln(salida,'Nº Caracteres = ',u-1);      {Escribe el nº de caracteres leidos}

if abierto_e         {Cierra ficheros}
then
close(entrada);

if abierto_s then
close(salida);

writeln('Operacion finalizada correctamente');
writeln('Pulse Enter para finalizar ...');
readln;
end.













02-May-2011 23:23
Nacho Cabanes (+32)

Dices "Veo que ni te has mirado el código". Obviamente, hasta que no lo publiques, no se puede mirar. Y no, como puedes ver tú mismo si relees la conversación, no lo habías publicado.


02-May-2011 23:50
D G

no?? Pero si estaba en este mismo mensaje... Bueno perdona, es que no se como se publica ni nada, yo simplemente lo envié junto al mensaje. Agradecería que me explicases como publicarlo ya que no tengo ni idea. Saludos


05-May-2011 00:06
Nacho Cabanes (+32)

Ya has visto la forma de publicarlo. Si lo enviaste como mensaje privado, corres el riesgo de que no llegue; si lo publicas en el foro, puedes comprobar instantáneamente que otras personas (quizá no sólo yo) van a poder darte ideas.

El problema es que tu planteamiento es "rebuscado". Primero prueba a que funcione de forma rápida y simple con un "rotor". Cuando eso esté claro, lo aplicas a tres rotores y lo amplías con el soporte de ficheros.

Si los tres rotores son un array de 3 cadenas, acortarías el código del programa casi a la tercera parte.

La idea básica, que ya comenté como "explicación" (para cada letra de la cadena a descifrar, ver en qué posición está de la secuencia de descifrado, y tomar el texto claro correspondiente a esa posición), podría equivaler a este código:


Program EnigmaBasico;

var
 textoClaro, secuenciaCifrado: string;
 aDescifrar, descifrado: string;
 i,j: byte;
 
begin
 textoClaro := ' .ABCDEFGHIJKLMNOPQRSTUVWXYZ';
 secuenciaCifrado := 'EKMFLG DQVZNTOWY.HXUSPAIBRCJ';
 
 aDescifrar := 'V.OM';
 descifrado := '';
 
 for i:= 1 to length(aDescifrar) do
   begin
   for j := 1 to length(secuenciaCifrado) do
     if aDescifrar[i] = secuenciaCifrado[j] then
       descifrado := descifrado + textoClaro[j];
   end;
   
 writeLn( descifrado );
end.






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)