Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: pacosn1111 en 21 Abril 2015, 17:55 pm



Título: Problema con rand y srand en este codigo
Publicado por: pacosn1111 en 21 Abril 2015, 17:55 pm
Estoy haciendo un pequeño motor de cifrado y tengo un problema con la función rand, y es que genera siempre el mismo numero, un numero negativo además, dejo aqui el código:

Código:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <math.h>

// variables globales

double claves[27][1000];
int clave[27];


// arrays globales
char letras[]="abcdefghijklmnopqrstuvwxyz ";
char cifrado[999999999];
char descifrado[999999999];

// prototipos de funciones
void generar_clave(int);
void ingresar_clave(int []);
int comprobar_repetir_vector(int, int []);
int comprobar_repetir_matriz(double, double [][1000]);
void arrancar_motor(int, int);
int suma(double);
double aleatorio(int, int);
void cifrar(int, int, char []);
void descifrar(int, char []);


// comprueba si un numero esta repetido en una matriz, si esta repetido devuelve 1, en caso contrario 0.
int comprobar_repetir_matriz(double numero, double matriz[][1000]) {

int x;
int y;
for(x=0; x<27; x++) {

for(y=0;y<1000;y++) {

if (numero==matriz[x][y]) {
return 1;
}
}

}
return 0;

}

// comprueba si un numero esta repetido en un vector, si esta repetido devuelve 1, en caso contrario 0.
int comprobar_repetir_vector(int numero, int vector[]){

int x;
for(x=0; x<27;x++) {

if(numero==vector[x]) {

return 1;

}
}
return 0;
}

// Devuelve la suma de las cifras de un numero
int suma(double numero) {

int resultado=0;
while (numero>0) {

resultado+=fmod(numero, 10);
numero/=10;
}
return resultado;
}

//Genera un numero aleatorio sin decimales dentro de un rango entre max y min.
double aleatorio(int max, int min) {


return rand () % (max-min+1) + min;


}
//Genera una clave optimidada y la guarda en la variable global clave.
void generar_clave(int numero_suma) {


int maximo, minimo, x, y, num_random;

int max=120;
int min=60;

maximo=numero_suma*max/20;
minimo=numero_suma*min/20;


for(x=0;x<27;) {
num_random=aleatorio(maximo, minimo);
if (comprobar_repetir_vector(num_random, &clave[0])==1) {
continue;
}
clave[x]=num_random;
x++;
}

printf("se ha generado la clave: \n");
for(y=0;y<27;y++) {

printf("(%d)", clave[y]);

}
printf("\n");
}

// Permite ingresar el valor de cualquier array en la variable global clave.
void ingresar_clave(int array[]) {

int x;

for(x=0;x<27;x++) {

clave[x]=array[x];
}

}
// Genera los numeros aleatorios correspondientes a cada letra y los guarda según corresponda en la matriz claves.
void arrancar_motor(int numero_cifras, int cantidad_numeros){

srand(time(NULL));

int y, z, h;
double num_random;

double min=(double)pow(10.0, numero_cifras-1);
double max=(double)pow(10.0, numero_cifras)-1;

for(z=0; z<27; z++) {
printf("Inicializando letra %c\n", letras[z]);
for(h=0; h<cantidad_numeros;) {
num_random=aleatorio(max, min);
printf("%lf", num_random);
if ((suma(num_random)==clave[z]) && (comprobar_repetir_matriz(num_random, claves))==0) {

claves[z][h]=num_random;
printf("%.0lf\n", num_random);
h++;



} else { continue;  }


}
}
printf("se ha generado la clave: \n");
for(y=0;y<27;y++) {

printf("(%d)", clave[y]);

}
printf("\ncon un numero de cifras de %d\n", numero_cifras);
}

// Cifra un texto usando la clave almancenada en la variable global clave, el resultado lo guarda en la variable global cifrado.
void cifrar(int numero_cifras, int cantidad_numeros, char texto[]) {


int letra, letrass, x;
char cifrado_inside[strlen(texto)*numero_cifras];
char string_auxiliar[numero_cifras-1];
for(letra=0; strlen(texto)>letra; letra++) {


for(letrass=0; letrass<27; letrass++) {

if (texto[letra]==letras[letrass]) {
sprintf(string_auxiliar, "%.0lf", claves[letrass][(int)(aleatorio(cantidad_numeros-1, 0))]);
strcat(cifrado_inside, string_auxiliar);
break;
}

}

}
strcpy(cifrado, cifrado_inside);

}

// Descifra un texto cifrado anteriormente usando la clave almancenada en la variable global clave, el resultado lo guarda en la variable global descifrado.
void descifrar(int numero_cifras, char cifrado[]) {


char auxiliar[numero_cifras];
int x, y=0, z;

for(x=0; x<strlen(cifrado); x++) {

auxiliar[y]=cifrado[x];
y++;


if(y==numero_cifras) {

for(z=0; z<27; z++) {

if(suma(atof(auxiliar))==clave[z]) {

descifrado[strlen(descifrado)]=letras[z];
y=0;
break;


}


}


}





}



}



En la función arrancar_motor hago un srand(time(NULL)) es decir inicializo rand pero no se por que me genera siempre el mismo numero, pero no en ejecuciones distintas, si no cada vez que en el for de arrancar motor llamo a la funcion aleatorio que usa rand para obtener un numero aleatorio me da el mismo numero, por ende la función arrancar motor se queda congelada desde el primer intento de generar un número bajo las condiciones que quiero.

Gracias de antemano.

Saludos.


Título: Re: Problema con rand y srand en este codigo
Publicado por: user-marcos en 21 Abril 2015, 19:54 pm
Ponlo sólo una vez y en el main.

Código
  1.  
  2. int main(){
  3.  
  4. srand(time(NULL));
  5.  
  6. return 0;
  7. }
  8.  
  9.  


Título: Re: Problema con rand y srand en este codigo
Publicado por: pacosn1111 en 21 Abril 2015, 21:16 pm
Ponlo sólo una vez y en el main.

Código
  1.  
  2. int main(){
  3.  
  4. srand(time(NULL));
  5.  
  6. return 0;
  7. }
  8.  
  9.  

Cuando lo tenía así funcionaba perfectamente el problema es que como es un .h, una librería (o biblioteca), no tiene funcion main... ¿ Donde lo pongo entonces ?

Saludos.


Título: Re: Problema con rand y srand en este codigo
Publicado por: ivancea96 en 21 Abril 2015, 21:43 pm
Lo mejor sería que lo llamases en el main, pese a que fuera una librería. O hacer una función para inicializar la librería.


Título: Re: Problema con rand y srand en este codigo
Publicado por: user-marcos en 21 Abril 2015, 21:55 pm
Una alternativa:
Código
  1. #include<iostream>
  2. #include<ctime>
  3. #include<cstdlib>
  4. using namespace std;
  5.  
  6. void Funcion_Princial();
  7. int Aleatorio();
  8.  
  9. int main()
  10. {
  11.  Funcion_Princial();
  12.  return 0;
  13. }
  14.  
  15. void Funcion_Princial()
  16. {
  17.  srand(time(NULL));
  18.  cout << Aleatorio()<<endl;
  19. }
  20. int Aleatorio()
  21. {
  22.  rand()%200;
  23. }
  24.  
Dejas la semilla en un módulo, y de este llamas a una función para que te de el nº


Título: Re: Problema con rand y srand en este codigo
Publicado por: pacosn1111 en 21 Abril 2015, 22:02 pm
Gracias por vuestras respuestas, me han servido de mucho.

Saludos.


Título: Re: Problema con rand y srand en este codigo
Publicado por: Miky Gonzalez en 26 Abril 2015, 20:09 pm
No es necesario complicarse tanto puedes añadir una llamada a function en tu libreria:

srand...

Y el usuario seguiria ejecutando la misma funcion sin interacción con esa función: cómodo, práctico y sencillo.