Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: hlastras en 17 Noviembre 2012, 23:36 pm



Título: Iniciandome en C
Publicado por: hlastras en 17 Noviembre 2012, 23:36 pm
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.


Título: Re: Iniciandome en C
Publicado por: Beakman en 18 Noviembre 2012, 00:23 am
No creo que sea TAN grande el texto. Supongo que debe haber un problema en el desarrollo del código.


Título: Re: Iniciandome en C
Publicado por: durasno en 18 Noviembre 2012, 00:40 am
Hola! subi el codigo para poder ayudarte. Saludos


Título: Re: Iniciandome en C
Publicado por: hlastras en 18 Noviembre 2012, 01:26 am
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


Título: Re: Iniciandome en C
Publicado por: hlastras en 18 Noviembre 2012, 01:28 am
Código:
#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


Título: Re: Iniciandome en C
Publicado por: 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


Título: Re: Iniciandome en C
Publicado por: 0xDani en 18 Noviembre 2012, 14:06 pm
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.


Título: Re: Iniciandome en C
Publicado por: hlastras en 18 Noviembre 2012, 17:13 pm
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:
Código:
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.


Título: Re: Iniciandome en C
Publicado por: hlastras en 22 Noviembre 2012, 21:48 pm
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


Título: Re: Iniciandome en C
Publicado por: rir3760 en 23 Noviembre 2012, 15:43 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>).

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++
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