Ultima duda de snakecode (violación de segmento)

Iniciado por pacosn1111, 24 Abril 2015, 19:35 PM

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

pacosn1111

Hola a todos, ya casi he conseguido crear snakecode (aunque arranca bastante lenta la funcion arrancar_motor), solo me falta conseguir que cifre y descifre, he creado las funciones pero algo estoy haciendo mal por que no funcionan bien, dejo el código que llevo:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <math.h>

// constantes

#define numero_de_letras 27

// variables globales

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


// 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 []);
int comprobar_repetir_matriz(int, double, double [][1000]);
void arrancar_motor(int, int);
int suma(double);
double aleatorio(int, int);
double aleatorio_cifras(int);
void cifrar(int, int, char []);
void descifrar(int, char []);

int main() {


generar_clave(32);
arrancar_motor(32, 20);

cifrar(32, 20, "prueba");
printf("%El mensaje cifrado es:\n %s\n", cifrado);
descifrar(32, cifrado);
printf("El mensaje descifrado es:\n %s \n", descifrado);
}



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

int x;
int y;
for(x=0; x<n-1; 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 n, int numero, int vector[]){

int x;
for(x=0; x<n-1;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;


}

double aleatorio_cifras(int cifras) {

int x;
int random;
char aux[2];
char num[cifras];

num[0]=0;
for(x=0; x<cifras; x++){

random=rand () % 10;

if((random==0) && (x==0)) { x--; continue;  }
sprintf(aux, "%d", random);
strcat(num, aux);

}
return atof(num);

}

//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<numero_de_letras;) {
num_random=aleatorio(maximo, minimo);
if (comprobar_repetir_vector(x, num_random, &clave[0])==1) {
continue;
}
clave[x]=num_random;
x++;
}

printf("se ha generado la clave: \n");
for(y=0;y<numero_de_letras;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<numero_de_letras;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;

for(z=0; z<numero_de_letras; z++) {
printf("Inicializando letra %c\n", letras[z]);
for(h=0; h<cantidad_numeros;) {
num_random=aleatorio_cifras(numero_cifras);
if (((fabs(suma(num_random)-clave[z])) < pow(1, -9999999999999)) && (comprobar_repetir_matriz(z, 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<numero_de_letras;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<numero_de_letras; 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<numero_de_letras; z++) {

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

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

}

}

}

}

}



Me da violación de segmento la función cifrar.

Para que veais mas o menos lo que debe de hacer os dejo el mismo algoritmo en python, lo escribí hace tiempo y funciona perfecto, es mas hasta arranca más rapido, lo estoy portando a C por cuestiones didácticas mas que nada:

Código (python) [Seleccionar]

# -*- encoding: utf-8 -*-

#snakecode is free software: you can redistribute it and/or modify
  # it under the terms of the GNU General Public License as published by
   #the Free Software Foundation, either version 3 of the License, or
   #(at your option) any later version.

   #SnakeCode is distributed in the hope that it will be useful,
   #but WITHOUT ANY WARRANTY; without even the implied warranty of
   #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   #GNU General Public License for more details.
   #
   #You should have received a copy of the GNU General Public License
  # along with this program.  If not, see <http://www.gnu.org/licenses/>.


#constantes

maxr=120
minr=60

import random

#Devuelve la suma de las cifras de un numero

def suma(numero):

resultado=0
while numero>0:
resultado+=numero%10
numero/=10
return resultado

#Genera una lista con Z numeros aleatorios de X cifras, cuyas cifras sumen Y cantidad

def generador_aleatorio(numero_de_suma, numero_de_cifras, cantidad_de_numeros):
max=""
min="1"
lista_numeros=[]

for x in range(0, numero_de_cifras):
max+="9"
for x in range(1, numero_de_cifras):
min+="0"

while cantidad_de_numeros>0:
var=random.randint(int(min), int(max))
if suma(var)==numero_de_suma and lista_numeros.count(var)==0:
cantidad_de_numeros-=1
lista_numeros.append(var)
print var
return lista_numeros

# Genera una clave optimizada automáticamente devolviendo una lista, esa lista puede ser utilizada posteriormente al inicializar el motor con init

def generar_clave(nc):

maximo=nc*maxr/20
minimo=nc*minr/20

pass_random=[]

while len(pass_random)<28:

var=random.randrange(minimo, maximo)
if pass_random.count(var)==0:
pass_random.append(var)

return pass_random

# Inicializa el motor, el primer parámetro es el numero de cifras y el segundo es la lista que contiene la clave, ambos parametros imprescindibles para cifrar y descifrar con exito, el tercer parámetro, que es opcional, es la cantidad de numeros por letra generados.

def init(nc, lista, nn=20):

global claves
global letras
global numero_cifras
numero_cifras=nc

claves={}
letras=( "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", " ")
for y in range(0, 28):
print "inicializando letra ", letras[y]
claves[letras[y]]=generador_aleatorio(int(lista[y]), nc, nn)

print "se ha generado la clave", lista, "con un numero de cifras de", nc


#Devuelve un texto cifrado pasandole un texto en claro

def cifrar(texto):

cifrado=""
for x in texto:

cifrado+=str(random.choice(claves[x]))

return cifrado

#Devuelve un texto en claro pasandole un texto cifrado

def descifrar(cifrado):

separado=[]
for x in range(0, len(cifrado), numero_cifras):

separado.append(cifrado[x:x+numero_cifras])

texto=""

for x in separado:
for y in claves:

if suma(int(x))==suma(int(claves[y][0])):

texto+=y

return texto




Gracias de antemano.

Saludos.




Seré mas específico, la función que da violación de segmento esta:


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<numero_de_letras; 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);

}





He logrado solucionarlo, pero ahora no cifra bien por que sale un caracter raro al principio de lo que está cifrado, es decir algo así:

@5206852228998504

El código que llevo ahora es este:

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<numero_de_letras; 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);

}


Ayudadme por favor.

Saludos.




Ya lo he resuelto, gracias de todas formas.