elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
29 Mayo 2012, 00:56  


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse)
| | |-+  Ejemplos de memoria dinamica en cifrado de Beaufort
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Ejemplos de memoria dinamica en cifrado de Beaufort  (Leído 225 veces)
do-while


Desconectado Desconectado

Mensajes: 604


Cuando me afeito, recuerdo porque me dejo barba.


Ver Perfil
Ejemplos de memoria dinamica en cifrado de Beaufort
« en: 21 Octubre 2011, 04:10 »

¡Buenas!

He visto que ultimamente hay bastantes preguntas sobre memoria dinamica. Aqui os dejo un pequeño programa que la utiliza varias veces y con distintos tipos de puntero. Espero que podais usarlo como ejemplo para resover vuestros propios problemas.

Para los interesados en criptografia, tengo que decir que es una variante del cifrado de Beaufort en el que se pueden utilizar varias claves para añadir seguridad al cifrado:

Código
/*
 
   Utilidad que cifra ficheros basandose en el cifrado de Beaufort con claves multiples
 
   Al ultilzar claves multiples, la longitud de la clave resultante sera el minimo comun
multiplo de todas las claves utilizadas.
 
   cifra +|- "claves" fichero_de_entrada fichero_de_salida
 
   +: cifrar
   -: descifrar
 
*/

 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
/* funcion que guarda en tokens las palabras contenidas en s y devuelve el numero de parabras extraidas */
int tokenize(char *s, char ***tokens);
 
/* carga en (*s) el contenido del fichero al que apunta f */
unsigned long cargar_fichero(FILE *f, unsigned char** s);
 
/*
 
calcula el coeficiente nsimo segun el siguiene criterio:
 
ultima_clave[posicion % longitud ultima_clave] -
penultima_clave[posicion % longitud penuultima_clave] +
antepenultima_clave[posicion % longitud antepenultima_clave] +
... + o - (segun el numero de claves) primera_clave[posicion % longitud primera_clave]
*/

int coeficiente(unsigned long posicion, char **claves, int nclaves);
 
/*
   cifrado[i] = coeficiente[i] + o - (depende del numero de claves) texto_plano[i] mod 256;
 
   tomando la clase de quivalencia positiva entre 0 y 255
*/

int cifrar(unsigned char *s, unsigned long longitud, char **claves, int nclaves);
 
 
/*
   texto_plando[i] = 1 o (-1) (depende del numero de claves) * (cifrado[i] - coeficiente[i]) mod 256;
 
   tomando la clase de quivalencia positiva entre 0 y 255
*/

int descifrar(unsigned char *s, unsigned long longitud, char **claves, int nclaves);
 
/*
 
   las siguientes funciones calculan el minimo comun multiplo y maximo comun divisor de dos enteros
 
*/

unsigned long mcm(unsigned long a, unsigned long b);
unsigned long mcd(unsigned long a, unsigned long b);
 
int main(int argc, char *argv[])
{
   FILE *f; /* fichero de entrada y de salida */
   char **claves = NULL; /* variable para guardar las claves introducidas */
   unsigned char *contenido = NULL; /* puntero para almacenar el contenido del fichero */
   unsigned long longitud, nclaves; /* longitud del fichero y numero de claves introducidas*/
 
   if(argc != 5)
   {
       printf("\ncomando: cifra +|- \"claves\" fic_entrada fic_salida\n\n+: cifrar\n-: descifrar\n");
   }
   else
   {
       if(!(f = fopen(argv[3] , "rb")))
           printf("No se puede abrir el fichero: %s\n", argv[3]);
       else
       {
           if((longitud = cargar_fichero(f,&contenido)) == (unsigned long)(-1))
           {
               printf("Ha ocurrido un error al cargar el contenido del fichero de entrada.\n");
               fclose(f);
           }
           else
           {
               if((nclaves = tokenize(argv[2] , &claves)) != (unsigned long)(-1))
               {
                   if(!strcmp(argv[1],"+"))
                   {
                       if(!cifrar(contenido,longitud,claves,nclaves))
                           printf("\nHa ocurrido un error en el proceso de cifrado.\n");
                       else
                       {
                           if(!(f = fopen(argv[4] , "wb")))
                               printf("No se puede abrir el fichero: %s\n", argv[4]);
                           else
                           {
                               fwrite(contenido,longitud,1,f);
                               fclose(f);
                           }
                       }
 
                       free(contenido);
 
                       for(longitud = 0 ; longitud < nclaves ; longitud++)
                           free(claves[longitud]);
                       free(claves);
                   }
                   else if(!strcmp(argv[1],"-"))
                   {
                       if(!descifrar(contenido,longitud,claves,nclaves))
                           printf("\nHa ocurrido un error en el proceso de descifrado.\n");
                       else
                       {
                           if(!(f = fopen(argv[4] , "wb")))
                               printf("No se puede abrir el fichero: %s\n", argv[4]);
                           else
                           {
                               fwrite(contenido,longitud,1,f);
                               fclose(f);
                           }
                       }
 
                       free(contenido);
 
                       for(longitud = 0 ; longitud < nclaves ; longitud++)
                           free(claves[longitud]);
                       free(claves);
                   }
                   else
                       printf("\ncomando: cifra +|- \"claves\" fic_entrada fic_salida\n\n+: cifrar\n-: descifrar\n");
               }
               else
               {
                   printf("\nHa ocurrido un error al cargar las claves.\n");
                   free(contenido);
               }
           }
       }
   }
 
   return 0;
}
 
unsigned long cargar_fichero(FILE *f,unsigned char **ptr)
{
   unsigned long pos, len;
 
   /* calculamos la longitud del fichero */
   pos = ftell(f);
   fseek(f,0,SEEK_END);
   len = ftell(f);
   fseek(f,pos,SEEK_SET);
 
   /* asignamos tantos bytes como tenga el fichero */
   if(((*ptr) = (unsigned char *) malloc(len * sizeof(unsigned char))) != NULL)
       /* y cargamos el contenido */
       fread((*ptr),len,1,f);
   else
       len = (unsigned long)(-1);
 
   return len;
}
 
int tokenize(char *s, char ***tokens)
{
   char **aux; /* variable auxiliar para ir añadiendo una cadena mas a la lista */
   char *palabra; /* palabra extraida de la cadena s*/
   int npalabras = 0,i; /* numero de palabras y contador para bucles */
 
   /* intentamos leer una palabra */
   palabra = strtok(s," ");
 
   (*tokens) = NULL;
 
   while(palabra)
   {
       /* si se ha encontrado una palabra incrementamos el recuento de palabras*/
       npalabras++;
 
       /* hacemos que aux contenga tantos punteros a char como paralbras haya */
       if(!(aux = (char **) realloc((*tokens) , npalabras * sizeof(char*))))
       {
           for(i = 0 ; i < npalabras - 1 ; i++)
               free((*tokens)[i]);
 
           free(*tokens);
           (*tokens) = NULL;
 
           return -1;
       }
       else
       {
           /* asignamos la ultima palabra leida */
           aux[npalabras - 1] = (char *) malloc(sizeof(char) * (strlen(palabra) + 1));
           strcpy(aux[npalabras - 1] , palabra);
 
           /* y hacemos que la variable de entrada/salida apunte al nuevo conjunto de palabras */
           (*tokens) = aux;
       }
 
       /* intentamos leer la siguiente palabra */
       palabra = strtok(NULL , " ");
   }
 
   return npalabras;
}
 
int coeficiente(unsigned long posicion, char **claves, int nclaves)
{
   int c=0;
   unsigned long j;
 
   for(j = 0 ; j < nclaves ; j++)
   {
       if((nclaves - 1 - j) % 2)
           c -= claves[j][posicion % strlen(claves[j])];
       else
           c += claves[j][posicion % strlen(claves[j])];
   }
 
   return c;
}
 
int cifrar(unsigned char *s, unsigned long longitud, char **claves, int nclaves)
{
   unsigned long i;
   char *clave;
   unsigned long long_clave=1;
 
   /* la longitud de la clave final sera el mcm de las longitudes de las claves */
   for(i = 0 ; i < nclaves ; i++)
       long_clave = mcm(long_clave , strlen(claves[i]));
 
   if(!(clave = (char*) malloc(long_clave * sizeof(char))))
       return 0;
 
   for(i = 0 ; i < long_clave ; i++)
       clave[i] = coeficiente(i,claves,nclaves);
 
   for(i = 0 ; i < longitud ; i++)
       s[i] = (nclaves * 256 + (clave[i % long_clave] + (1 - 2 *(nclaves % 2)) * s[i])) % 256;
 
   free(clave);
 
   return 1;
}
 
int descifrar(unsigned char *s, unsigned long longitud, char **claves, int nclaves)
{
   unsigned long i;
   char *clave;
   unsigned long long_clave=1;
 
   for(i = 0 ; i < nclaves ; i++)
       long_clave = mcm(long_clave , strlen(claves[i]));
 
   if(!(clave = (char*) malloc(long_clave * sizeof(char))))
       return 0;
 
   for(i = 0 ; i < long_clave ; i++)
       clave[i] = coeficiente(i,claves,nclaves);
 
   for(i = 0 ; i < longitud ; i++)
       s[i] = (nclaves * 256 + ((1 - 2 * (nclaves % 2)) * (s[i] - clave[i % long_clave]))) % 256;
 
   free(clave);
 
   return 1;
}
 
unsigned long mcm(unsigned long a, unsigned long b)
{
   return (a * b) / mcd(a,b);
}
 
unsigned long mcd(unsigned long a, unsigned long b)
{
   if(a < b)
   {
       a ^= b;
       b ^= a;
       a ^= b;
   }
 
   if(!b)
       return a;
 
   return mcd(b , a % b);
}
 

Se debe utilizar desde la linea de comandos, por lo que es recomendable dejar el ejecutable en c:\windows\system32 para sistemas windows, \bin en sistemas UNIX y en general, en el directorio en el que se encuentren por defecto los comandos del sistema.

Para cifrar un fichero llamado "prueba" con la clave "clave de prueba" y como fichero de salida "cifrado", se debera hacer:
Código:
cifra + "clave de prueba" prueba cifrado
suponiendo que nombre del ejecutable sea cifra.

Para obtener el texto plano se utilizara la misma sintaxis utilizando el parametro - en lugar de +.

¡Saludos y espero que os sirva de referencia!

PD: Si veis algun error avisad, que uno es humano y por lo tanto propenso a cometer errores. Lo mismo si teneis alguna sugerencia.

¡Saludos!


En línea

¡¡¡Feliz año nuevo!!!
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Operadores de gestion dinamica de memoria en C++...
Programación General
BADBYTE-K 2 1,095 Último mensaje 25 Diciembre 2003, 08:52
por BADBYTE-K
Memoria dinamica en dev c++
Programación C/C++
vietnamita 1 2,175 Último mensaje 13 Noviembre 2008, 23:35
por Flakito81
Problema con memoria dinamica « 1 2 »
Programación C/C++
^Tifa^ 23 1,431 Último mensaje 30 Mayo 2009, 12:32
por emaguana
ayuda memoria dinamica c++
Programación C/C++
winroot 6 2,717 Último mensaje 24 Febrero 2010, 22:32
por Littlehorse
Clases y memoria dinamica ¬¬
Programación C/C++
.:BlackCoder:. 7 2,062 Último mensaje 21 Marzo 2010, 23:34
por Littlehorse
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines