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++){
if((random==0) && (x==0)) { x--; continue; }
}
}
//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++) {
}
}
// 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){
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("\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:
# -*- 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í:
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.