[ Foro de Pascal ]
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 decodicar (o codicar 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 codicado 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 supercie, devuelva una posicion.
Conguracion rotor1
' .ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'EKMFLG DQVZNTOWY.HXUSPAIBRCJ'
Conguracion rotor2
' .ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'AJDKSIR.UXBLHWTMCQGZNP YFVOE'
Conguracion re
ector3
' .ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'.
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.
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.
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!
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.
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.
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
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.)