Iniciandome en C

Iniciado por hlastras, 17 Noviembre 2012, 23:36 PM

0 Miembros y 1 Visitante están viendo este tema.

hlastras

Buenas,

os planteo una duda que no se como resolverla
El caso es que estoy programando un metodo simulador de la maquina enigma, un texto(en mi caso 450 caracteres) y una palabra criba que aparece en el texto descifrado, el programa va probando con todas las claves posibles descifrando el texto y mirando si esta la palabra criba.

Para textos muy cortos funciona perfectamente, el programa finaliza. Pero cuanto mas grande es el texto a descifrar antes se para el programa, sin dar mensaje de error. No se si es por falta de memoria o xq tiene un tiempo maximo de ejecucion.
¿Teneis alguna idea?

Un saludo y gracias de antemano.

Beakman

No creo que sea TAN grande el texto. Supongo que debe haber un problema en el desarrollo del código.

durasno

Hola! subi el codigo para poder ayudarte. Saludos
Ahorrate una pregunta, lee el man

hlastras

pues algo asi como un texto de 450caracteres procesarlo mas de un millon de veces


el codigo es algo largo, pero si quereis os le pongo

hlastras

#4
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>



static char alfabeto[26] = {'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'};
static int lalfabeto=26;
static int M[5] = {16, 4, 21, 9, 25};
static int TD[5][26]={{4,10,12,5,11,6,3,16,21,25,13,19,14,22,24,7,23,20,18,15,0,8,1,17,2,9},
{0,9,3,10,18,8,17,20,23,1,11,7,22,19,12,2,16,6,25,13,15,24,5,21,14,4},
{1,3,5,7,9,11,2,15,17,19,23,21,25,13,24,4,8,22,6,0,10,12,20,18,16,14},
{4,18,14,21,15,25,9,0,24,16,20,8,17,7,23,11,13,5,19,6,10,3,2,12,22,1},
{21,25,1,17,6,8,19,24,20,15,18,3,13,7,11,23,0,22,12,9,16,14,5,4,2,10}};
static int TE[26]={24,17,20,7,16,18,11,3,15,23,13,6,14,10,12,8,4,1,5,25,2,22,21,9,0,19};
static int TI[5][26]={{20,22,24,6,0,3,5,15,21,25,1,4,2,10,12,19,7,23,18,11,17,8,13,16,14,9},
{0,9,15,2,25,22,17,11,5,1,3,10,14,19,24,20,16,6,4,13,7,23,12,8,21,18},
{19,0,6,1,15,2,18,3,16,4,20,5,21,13,25,7,24,8,23,9,22,11,17,10,14,12},
{7,25,22,21,0,17,19,13,11,6,20,15,23,16,2,4,9,12,1,18,10,3,24,14,8,5},
{16,2,24,11,23,22,4,13,5,19,25,14,18,12,21,9,20,3,10,6,8,0,17,15,7,1}};
static int rotor[5]={0,1,2,3,4};




char *enigma(int *R, char *pos_ini, char *txt);
int tamanyo(char *txt);
char *num2text(int *Tfin, int tamanyotexto);
int cifradoIndirecto(int X, int *P, int *R);
int cifradoEspejo(int X);
int cifradoDirecto(int X, int *P, int *R);
void girarRotor(int *P, int *R);
int *text2num(char *txt, int tamanyotexto);

void Buscar(char *criba, char *texto);
void imprimir(int *b, char *n, char *txt);
int diferentesRotores(int *rot); //0false 1true
int contienecriba(char *criba, char *textoDescifrado); //0false 1true

int main(){
struct timeval t1, t2;
unsigned int v1, v2;
struct timezone tz;
char criba[50], texto[500];
printf("Introduce la palabra de criba en mayusculas Y SIN ESPACIOS!\n");
scanf("%s", criba);
printf("Introduce texto a descifrar en mayusculas, sin caracteres epeciales ni espacios\n");
scanf("%s", texto);


gettimeofday (&t1, &tz);
v1=t1.tv_sec;
Buscar(criba, texto);
gettimeofday (&t2, &tz);
v2=t2.tv_sec;

printf("%u seg\n",(v2-v1));

return 0;
}


char *enigma(int *R, char *pos_ini, char *txt){
int tamanyotexto=tamanyo(txt);
int *T=text2num(txt, tamanyotexto); //Mensaje convertido a numeros
int *P=text2num(pos_ini, 3); //Posiciones iniciales de los rotores en numeros
int X;
int *Tfin=(int*)malloc(tamanyotexto * sizeof(int));//Mensaje descodificado(en numeros)//AVISOOOO RESERVA MEMORIA DINAMICA

//Recorre todo el mensaje original, y codifica cada letra a su correspondiente
int i;
for (i = 0; i < tamanyotexto; i++) {
girarRotor(P, R);
X=T[i];
X=cifradoDirecto(X, P, R);
X=cifradoEspejo(X);
X=cifradoIndirecto(X, P, R);
Tfin[i]=X;
}

char *resultado=num2text(Tfin, tamanyotexto);
return resultado;
}

int tamanyo(char *txt){
int largo=0;
while (txt[largo]!='\0') largo++;
return largo;
}

int *text2num(char *txt, int tamanyotexto){
int *T=(int*)malloc(tamanyotexto * sizeof(int));
char a;
int n, i, j;
for (i = 0; i < tamanyotexto; i++) {
a=txt[i];
n=0;
for (j = 0; j < lalfabeto; j++) {
if (a==alfabeto[j]){
n=j;
}
}
T[i]=n;
}
return T;
}

void girarRotor(int *P, int *R){
if(P[0]==M[R[0]]){

if(P[1]==M[R[1]]){
P[2]=(P[2]+1)%26;
P[1]=(P[1]+1)%26;
P[0]=(P[0]+1)%26;
}else{
P[1]=(P[1]+1)%26;
P[0]=(P[0]+1)%26;
}
}else{
P[0]=(P[0]+1)%26;
}
}

int cifradoDirecto(int X, int *P, int *R){
int i;
for (i = 0; i < 3; i++) {

X=(X+P[i])%26;
X=TD[R[i]][X];
X=(X-P[i])%26;
if(X<0){
X=26+X;
}
}
return X;
}

int cifradoEspejo(int X){
X=TE[X];
return X;
}

int cifradoIndirecto(int X, int *P, int *R){
int i;
for (i = 2; i >= 0; i--) {
X=(X+P[i])%26;
X=TI[R[i]][X];
X=(X-P[i])%26;
if(X<0){
X=26+X;
}
}
return X;
}

char *num2text(int *Tfin, int tamanyotexto){
char *x=(char*)malloc(tamanyotexto * sizeof(int));
char t;
int i;
for (i = 0; i < tamanyotexto; i++) {
t=alfabeto[Tfin[i]];
x[i]=t;
}
return x;
}


void Buscar(char *criba, char *texto){
int rot[3];
int i, j, k, l, m, q;

for (i = 0; i < 5; i++) {
rot[0]=rotor[i];
getchar();
for (j = 0; j < 5; j++) {
rot[1]=rotor[j];
for (k = 0; k < 5; k++) {
rot[2]=rotor[k];


if(diferentesRotores(rot)==1){
printf("%d%d%d\n",rot[0]+1,rot[1]+1,rot[2]+1);

char posiciones[3];//String de las posiciones de los rotores (ej. "ABR")
for (l = 0; l < 26; l++) {
posiciones[0]=alfabeto[l];
for (m = 0; m < 26; m++) {
posiciones[1]=alfabeto[m];
for (q = 0; q < 26; q++) {
posiciones[2]=alfabeto[q];

//Aqui ya esta la clave generada
char *textoDescifrado=enigma(rot, posiciones, texto);
//c++;
if(contienecriba(criba, textoDescifrado)!=0){
imprimir(rot, posiciones, textoDescifrado);
}



}

}

}

}

}
}
}
}

int diferentesRotores(int *b){
if(b[0]==b[1] || b[0]==b[2] || b[1]==b[2]){
return 0;
}
return 1;
}

int contienecriba(char *enc, char *pal){
int i=0, j=0, veces=0;

while(pal[i]){
if(pal[i]==enc[j])j++;
else j=0;
if(!enc[j]){
veces++;
j=0;
}
i++;
}
return veces;

}

void imprimir(int *b, char *n, char *txt){
printf("-------\n%d%d%d-%c%c%c\n%s\n",b[0],b[1],b[2],n[0],n[1],n[2],txt);

}


me falta comentarlo, asique si no entendeis algo preguntar

Gracias por la ayuda

hlastras

Bueno, probandolo en otra maquina, la de la uni que trabaja bajo UNIX, lo he compilado con esa y lo he ejecutado y parece que avanza mas, pero hay un punto en el que me sale el mensaje de VIOLACION DE SEGMENTO, que segun nos explico el profesor es cuando accedemos a memoria que no nos corresponde como usuarios

0xDani

Cita de: hlastras en 18 Noviembre 2012, 02:02 AM
Bueno, probandolo en otra maquina, la de la uni que trabaja bajo UNIX, lo he compilado con esa y lo he ejecutado y parece que avanza mas, pero hay un punto en el que me sale el mensaje de VIOLACION DE SEGMENTO, que segun nos explico el profesor es cuando accedemos a memoria que no nos corresponde como usuarios

Ahi el problema suele estar en en el uso de punteros o arrays, por ejemplo si tienes una variable que hace de indice y no la reseteas a 0 a cada iteracion de un bucle o algo asi. Revisa como usas los punteros y los arrays.

Saludos.
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM

hlastras

Ahi esta el problema que todavía tengo muy verdes los punteros jajaja en cuanto llege a casa vuelvo a revisar a fondo los punteros.

Bueno y otras dudas que tengo las planteo aqui ya por si alguien me puede responder

En este mismo programa, hay que introducir un texto que se desconoce su longitud, puede ser 10 o 1000. Como puedo hacer que reserve la memoria necesaria, segun lo que introduces.
Porque por ejemplo aqui tengo:

char criba[50], texto[500];
printf("Introduce la palabra de criba en mayusculas Y SIN ESPACIOS!\n");
scanf("%s", criba);

pero tengo que introducir la longitud del array char (500) y si lo creo solo con un puntero se me sale de la memoria

Se puede programar un entorno grafico, asi con ventanas de windows y tal de una manera "sencilla" en C? porque siempre que busco algo sobre esto siempre me sale c++

Un saludo y perdon por mis dudas de novato.

hlastras

Bueno, tema solucionado.
El problema era la gestion de memoria, que acababa usando toda la memoria disponible y cuando se llenaba me daba el error.
Para solucionarlo he usado free() para liberar las variables que no se usan mas

Gracias por la ayuda.
Alguien sabe algo sobre mis anteriores dudas?

Un saludo

rir3760

Cita de: hlastras en 18 Noviembre 2012, 17:13 PM
En este mismo programa, hay que introducir un texto que se desconoce su longitud, puede ser 10 o 1000. Como puedo hacer que reserve la memoria necesaria, segun lo que introduces.
Primero reservas un bloque de memoria mediante la función malloc, si este se llena incrementas la capacidad con la función realloc (Prototipos de ambas en <stdlib.h>).

Cita de: hlastras en 18 Noviembre 2012, 17:13 PMSe puede programar un entorno grafico, asi con ventanas de windows y tal de una manera "sencilla" en C? porque siempre que busco algo sobre esto siempre me sale c++
Si apenas estas empezando en C seria mejor que dejaras el desarrollo de aplicaciones de ventana para mas adelante. O puedes revisar los temas relacionados mediante el motor de búsqueda de los foros.

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language