elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Estamos en la red social de Mastodon


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Como cifrar letra por letra en C++
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 2 3 4 5 6 [7] Ir Abajo Respuesta Imprimir
Autor Tema: Como cifrar letra por letra en C++  (Leído 64,920 veces)
amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: Como cifrar letra por letra en C++
« Respuesta #60 en: 17 Junio 2013, 11:37 am »

Podrías utilizar los parametros argv, te ahorras ese fgets y esa aberración llamada scanf.
Perdiendo facilidad y sencillez...

Personalmente, si eres un poco peresozo y no quieres usar teclado. Simplemente pones esto al ejecutar el programa

Código
  1. programa < fichero.txt

Y en fichero pones todos los parámetros del teclado.

Código
  1. while (getchar()!='\n');

Venga hombre.
Es un método tan válido como cualquier otro para "limpiar" el buffer del teclado.

P.D: Yo dejo el tema, desde mi punto de vista un desplazamiento de bits o un xor, es mucho mejor que el de César, yo no daría más importancia a esto de verdad.
Bueno es curiosidad educativa  :silbar:


En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: Como cifrar letra por letra en C++
« Respuesta #61 en: 17 Junio 2013, 14:36 pm »

Código demasiado largo y poco eficiente, para algo tan simple como el cifrado de César, y sin hablar del array.


Ya,ya, pero para mejor eficiencia ya están los dos posteados con anterioridad, el de CCross/cypscal/mío con una función y el uso de la librería ctype y el anterior mío sin más uso que el de el caracter ascii. Aún espero una propuesta "completa" por parte tuya, donde se pueda introducir la frase y el desplazamiento, no tan solo mover tres posiciones los caracteres sin tener en cuenta que si se llega al final se vuelve al comienzo del abecedario e incluir tanto minúsculas como mayúsculas e incluya sus printf y toda esa retaila.

De todas formas olvidas lo fundamental:


Creo que no has pillado la "intención" de la propuesta. Se trata de ver el "potencial" de los intervinientes en el foro y que en base a este tema hagan propuestas ingeniosasy/o "raritas" con la única finalidad de exprimir el ingenio, plasmar los conocimientos y ayudar/enseñar unos de otros.

Código
  1.        printf("Ingrese una cadena: ");
  2.        fgets (frase,255,stdin);
  3.  
  4.         puts("Ingrese desplazamiento: (1-25) ");
  5.         scanf ("%d",&desplazamiento);
  6.  

Podrías utilizar los parametros argv, te ahorras ese fgets y esa aberración llamada scanf.

Sí hombre, y volver cuarenta años atrás a programar tipo MS-DOS metiendo todo a mano y a base de comandos. No, lo siento, pero yo ya pasé esa época, tanto que por líneas de comandos no hagoun código ni de coñ*. Como ya he menciona en alguna ocasión, en mi caso al menos, un pasito atrás ni "pá" coger impulso.

Código
  1. while (getchar()!='\n');

Venga hombre.


¿Alguna sugerencia diferente para limpiar el buffer?. No creo que seas de los que usan fflush (stdin). Reconozco humildemente que mis conocimientos en este mundillo del C/C++ son aún escasos, pero ¿alguna propuesta alternativa que nos ilumine a los neófitos?

Un saludo.

Yo un "Saludito", como se dice por mi tierra. Lamento que hallas "agriado" un poco el tema con tu actitud ¿prepotente?, cuando mi única finalidad era que el personal que nos sigue se animase al "juego" de proponer alternativas al tema del cifrado César, como podría haber sido cualquier otro. Era sólo un reto que, por lo que veo y leo, tú te lo has tomado como algo personal, cosa que no entiendo. Y menos aún el que, repito/insisto no hallas hecho una propuesta alternativa en toda regla. Para criticar por criticar y deshagorte creo que existen otros foros más apropiados.



P.D: Yo dejo el tema, desde mi punto de vista un desplazamiento de bits o un xor, es mucho mejor que el de César, yo no daría más importancia a esto de verdad.

Pues ya ves, esa es una sugerencia, que no aportación, que no caerá en saco roto, aunque intuyendo tu preparación habría esperado más de tí.

Como diría amchacon:

Perdiendo facilidad y sencillez...

Personalmente, si eres un poco peresozo y no quieres usar teclado. Simplemente pones esto al ejecutar el programa

Código
  1. programa < fichero.txt

Y en fichero pones todos los parámetros del teclado.
Es un método tan válido como cualquier otro para "limpiar" el buffer del teclado.
Bueno es curiosidad educativa :silbar:

En fin, que si se te hace muy largo el array del último post, y cuya única finalidad era la que era- releete el post para que lo entiendas bien- te dejo "otro" código con dos arrays, aunque más cortitos que el anterior , eso sí sin usar librerías, ni la operación módulo ni tan siquiera el código ascii, a"a pelo" vamos.....¡y que siga el juego! :

Código
  1. #include <stdio.h>
  2. int main(void)
  3. {
  4.    char frase[256] = {0};
  5.    int i=0,j=0,desplazamiento=0;
  6.    char ABC[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
  7.    char abc[] = {"abcdefghijklmnopqrstuvwxyz"};
  8.    while(1)
  9.    {
  10.        printf("Ingrese una cadena: ");
  11.        fgets (frase,255,stdin);
  12.        do
  13.        {
  14.            puts("Ingrese desplazamiento: (1-25) ");
  15.            scanf ("%d",&desplazamiento);
  16.            while (getchar()!='\n');
  17.        }while (desplazamiento<0 || desplazamiento>25);
  18.        for(i = 0; frase[i]; i++)
  19.        {
  20.            for(j = 0; j<26; j++)
  21.                {
  22.  
  23.                    if ( frase[i]==' ')
  24.                        break;
  25.                    if (frase[i]==abc[j] && j+ desplazamiento<26)
  26.                    {
  27.                        frase[i] =  abc[j+ desplazamiento];
  28.                        break;
  29.                    }
  30.                    else if (frase[i]==abc[j] && j+ desplazamiento>=26)
  31.                    {
  32.                        frase[i] =  ABC[j+ desplazamiento-26];
  33.                        break;
  34.                    }
  35.                    else if (frase[i]==ABC[j] && j+ desplazamiento<26)
  36.                    {
  37.                        frase[i] =  ABC[j+ desplazamiento];
  38.                        break;
  39.                    }
  40.                    else if (frase[i]==ABC[j] && j+ desplazamiento>=26)
  41.                        {
  42.                            frase[i] =  abc[j+ desplazamiento-26];
  43.                            break;
  44.                    }
  45.                }
  46.        }
  47.         printf("Cadena cifrada: %s\n\n", frase);
  48.         for(i = 0; frase[i]; i++)
  49.        {
  50.            for(j = 0; j<26; j++)
  51.                {
  52.  
  53.                    if ( frase[i]==' ')
  54.                        break;
  55.                    if (frase[i]==abc[j] && j- desplazamiento>=0)
  56.                    {
  57.                        frase[i] =  abc[j- desplazamiento];
  58.                        break;
  59.                    }
  60.                    else if (frase[i]==abc[j] && j- desplazamiento<0)
  61.                    {
  62.                        frase[i] =  ABC[j-desplazamiento+26];
  63.                        break;
  64.                    }
  65.                    else if (frase[i]==ABC[j] && j- desplazamiento>=0)
  66.                    {
  67.                        frase[i] =  ABC[j- desplazamiento];
  68.                        break;
  69.                    }
  70.                    else if (frase[i]==ABC[j] && j- desplazamiento<=0)
  71.                        {
  72.                            frase[i] =  abc[j-desplazamiento+26];
  73.                            break;
  74.                    }
  75.                }
  76.        }
  77.         printf("Cadena descifrada: %s\n\n", frase);
  78.    }
  79.    return 0;
  80. }
  81.  

Saluditos!


« Última modificación: 17 Junio 2013, 23:59 pm por leosansan » En línea

Royca3

Desconectado Desconectado

Mensajes: 45



Ver Perfil WWW
Re: Como cifrar letra por letra en C++
« Respuesta #62 en: 17 Junio 2013, 20:14 pm »

emm! Sera que alguien puede pasarme un manual de C++??
Bien explicado y completo? en los que hayan aprendido ustedes
saludos

(tengo unos pero, no entiendo claramente)
En línea

Homo erectus
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: Como cifrar letra por letra en C++
« Respuesta #63 en: 18 Junio 2013, 20:33 pm »

La verdad es que, en principio y sólo en principio, el cifrado César es muy endeble ante un simple ataque por "fuerza bruta". Bastaría ir probando con un desplazamiento de 0 a 26 y ver cuando obtenemos "algo" razonable/entendible.

Como muestra esta imagen en que se observa el cifrado y el "ataque" para descifrarlo:



Cosa que consigo con este simple código:

Código
  1. #include <stdio.h>
  2. int main (void)
  3. {
  4.    int i,n=0,k=0;
  5.    char frase [256];
  6.  
  7.    while (1)
  8.    {
  9.        n=0;
  10.        puts ("\nIntroduce una frase: ");
  11.        fgets (frase,255,stdin);
  12.        do
  13.        {
  14.            printf ("\nIndica el desplazamiento: ");
  15.            scanf ("%d",&n);
  16.            while (getchar()!='\n');
  17.        }while (n<0 || n>25);
  18.  
  19.        for (i=0;frase[i];i++)
  20.        {
  21.            if ((frase [i]>('z'-n) && frase [i]<='z') || (frase [i]>('Z'-n) && frase [i]<='Z' ))
  22.                frase [i]=frase [i]-26+n;
  23.            else if (frase [i]>='a' && frase [i]<=('z'-n) || (frase [i]>='A' && frase [i]<=('Z'-n) ))
  24.                frase [i]+=n;
  25.        }
  26.        printf("\nCodificada con desplazamiento %d \n",n);
  27.        printf ("%s\n",frase);
  28.        puts("\nY ahora descodificada: ");
  29.        for (k=0;k<26;k++)
  30.        {
  31.            for (i=0;frase[i];i++)
  32.            {
  33.                if ((frase [i]<('a'+k) && frase [i]>=('a')) || (frase [i]<('A'+k) && frase [i]>=('A') ))
  34.                frase [i] =frase [i]+26-k;
  35.                else if ((frase [i]>=('a'+k) && frase [i]<=('z') )|| (frase [i]>=('A'+k) && frase [i]<=('Z') ))
  36.                    frase [i]-=k;
  37.            }
  38.            printf ("%s\n\n",frase);
  39.            system ("pause");
  40.        }
  41.    }
  42.    return 0;
  43. }
  44.  

Pero, pero .... con una pequeña variante lo podríamos hacer "casi" indescifrable, según comenta la Wikipedia:

"El cifrado Vigenère usa el cifrado César con un
desplazamiento diferente en cada posición del texto;
el valor del desplazamiento se define usando una
palabra clave repetitiva. Si la palabra clave fuera
escogida al azar y tan larga como el mensaje
(para que no se repita), el sistema resultante sería,
en teoría, indescifrable."



No creo que sea para tanto, pero cualquiera le lleva la contraria a Wikipedia. Como ya comenté en otro post anterior, más información en Cifrado César cortesía de Wikipedia.

Por si acaso, yo lo he intentado usando un valor aleatorio como desplazamiento para cada letra, con lo que el ataque por fuerza bruta anterior no sirve de nada, tendría que ser algo más refinado y respaldado con "potencia".

Como muestra otra imagen:



Pueden observar que la letra "a", que en el cifrado normal sería siempre la misma letra desplazada,  ahora cambia debido a que he usado un array aleatorio para cifrar la frase y sin ese array se haría muy "cuesta arriba" el descifrado ya que incluso el análisis por frecuencia fallaría, por la aleatoriedad mencionada.

Y he aquí la pequeña, pero "potente", variación:


Código
  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <time.h>
  4. void cesar (char *cadena , int letra, int *key);
  5. int main()
  6. {
  7.    int  i=0,des=0, letra=0;
  8.    srand((unsigned) time(NULL));
  9.    char cadena[0x100]={0};
  10.    puts("Ingrese una cadena: ");
  11.    gets (cadena);
  12.    int key[strlen(cadena)],_key[strlen(cadena)];
  13.     for (i = 0;cadena[i]; i++)
  14.    {
  15.        key[i] = rand() % 0x1A+1 ;
  16.        _key[i] = -key[i];
  17.    }
  18.    cesar (cadena,0x61,key);
  19.    printf("\nCifrado es: %s \n", cadena);
  20.    cesar (cadena,0x7A,_key);
  21.    printf("\nDecifrado es: %s \n", cadena);
  22.    return 0;
  23. }
  24. void cesar (char cadena[] , int letra, int *des)
  25. {
  26.    int i,letra1=0;
  27.    for(i = 0; cadena[i]; i++)
  28.     {
  29.        if ( cadena[i]==' ')
  30.            continue;
  31.        letra1=letra;
  32.        if(isupper(cadena[i])!=0)
  33.            letra1-=0x20;
  34.        cadena[i] =((cadena[i]-letra1+des[i] )%0x1A)+letra1;
  35.      }
  36. }


Como veis he sustituido los números decimales por sus correspondientes hexadecimales, sólo por darle un aspecto más críptico al tema.

 Y el código propuesto tiene un valor añadido y es que cada mensaje usa un array aleatorio diferente en cada caso, por lo que la "interseptación" de dos mensajes no ayudaría en nada a los desencriptadores.

¡Anímate!, e intenta el descifrado de:

Código
  1. Cifrado es: Uhmvhvcjsakoo Mqoug ctz Xwrvdm Gycgs


 Saluditos!
    
« Última modificación: 22 Junio 2013, 13:51 pm por leosansan » En línea

amchacon


Desconectado Desconectado

Mensajes: 1.211



Ver Perfil
Re: Como cifrar letra por letra en C++
« Respuesta #64 en: 18 Junio 2013, 22:44 pm »

Muy interesante Leo  ;-)

En mis tiempos hize un programa para descifrar palabras cifradas con César:

https://dl.dropboxusercontent.com/u/69551225/Desencriptador%20Secuencias%20%28WINDOWS%29.rar
https://dl.dropboxusercontent.com/u/69551225/Desencriptador%20Secuencias%20%28SOURCE%29.zip

Tienes que representar las letras con números y el programa busca palabras que sigan ese patrón. Por ejemplo:

Citar
Amanda

Introduciríamos en el programa:

Citar
121341

(cada letra se corresponde con un número).

El programa entonces, detectaría que la primera letra,tercera y quinta letra son iguales. Entonces buscaría en su base de datos palabras que sigan ese patrón. Los nombres obtenidos se guardan en un txt (deseché mostrarlos por pantalla por si la lista fuese muyy larga).
En línea

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: Como cifrar letra por letra en C++
« Respuesta #65 en: 22 Junio 2013, 09:24 am »

Muy interesante Leo  ;-)


Gracias, gracias e idem por el tuyo.

Ya para finalizar el tema no quería quedarme sin "actualizar" el cifrado César, que por motivos históricos se reducía al abecedario, y permitir el cifrado de buena parte del código ascii. Vamos que al menos contuviera símbolos tan actuales como $, ~, #, @ <, >, " ¿, ¡ etc. Una salida como ejemplo:


Código
  1. Ingrese una cadena:
  2. "leosan@san.com! ¿san? #leo+san|=\12345!==$$
  3.  
  4. Cifrado es: Vêt&#9500;ôíêc£x}enªºn &#9571;&#9617;®&#9559;M C&#9500;ç&#9532;k¢qçðv|3xKfT=pYxx
  5.  
  6. Decifrado es: "leosan@san.com! ¿san? #leo+san|=\12345!==$$

Y esta vez no voy a colgar el código, creo que si han seguido los posts anteriores no tendrán ninguna dificultad en obtenerlo. Sólo pretendía poner de manifiesto que, como ya comenté, el cifrado César "actual" va más allá del simple abecedario original.


Saluditos!
« Última modificación: 22 Junio 2013, 20:29 pm por leosansan » En línea

do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: Como cifrar letra por letra en C++
« Respuesta #66 en: 22 Junio 2013, 13:43 pm »

(He corregido algun error que había en alguna cadena. Ahora si que creo que está todo bien)

He añadido comprobación de parámetros en la función vigenere, que es donde deberían estar si se quiere añadir a una librería.

Ahora, en lugar de definir un nombre de fichero temporal mediante una constante simbolica, utilizo tmpnam() para asegurarme de que el nombre no se corresponda con ningún archivo existente.

¡Buenas!

Como estáis recopilando códigos de cifrado, aquí os dejo el del cifrado de Vigenere.

El código es un podo largo. El cifrado de Vigenere está al principio. Hay repeticion de código, pero lo he hecho así para evitar introducir demasiadas condiciones en el codigo de cifrado, ya que para archivos extensos el algoritmo sería muy lento. El codigo que hay en main es basicamente para leer y clasificar los datos de la linea de comandos (por eso es tan largo). Al final os dejo la sintaxis de llamada desde la linea de comandos y algunos ejemplos:

Código
  1. /*
  2.  * Cifrado de Vigenere
  3.  *
  4.  * Linea de comandos: nombre_programa -a alfabeto -[c|f] cadena|fichero -k clave -s [fichero_salida | std]
  5.  *
  6.  * Cifra los caracteres de la cadena (parametros -c "Cadena") o el fichero (parametros -f nombre_del_fichero)
  7.  * que coincidan con los del alfabeto (- que se le pasa, utilizando la clave dada (parametros -k clave)
  8.  *
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14.  
  15. #define MAX_STRLEN 256
  16.  
  17. /*
  18.  * Las siguientes constantes sirven para decidir si la funcion vigenere actuara sobre una cadena o un fichero
  19.  */
  20. #define IN_CADENA  0
  21. #define IN_FICHERO 1
  22.  
  23. /*
  24.  * Constantes para decidir si la funcion vigenere cifrara o descifrara la entrada
  25.  */
  26. #define ACCION_CIFRAR    0
  27. #define ACCION_DESCIFRAR 1
  28.  
  29. /*
  30.  * vigenere(tipo entrada (cadena o fichero), cadena con texto o nombre de fichero con el input,
  31.  * alfabeto, clave, cifrar|descifrar, fichero de salida (stdin o nombre de arcivo))
  32.  *
  33.  * valor de retorno: 0 si algo falla, 1 si todo va bien.
  34.  */
  35.  
  36. unsigned long flen(FILE *f)
  37. {
  38.    unsigned long pos,len;
  39.  
  40.    pos = ftell(f);
  41.    fseek(f,0,SEEK_END);
  42.    len = ftell(f);
  43.    fseek(f,pos,SEEK_SET);
  44.  
  45.    return len;
  46. }
  47.  
  48. int vigenere(int modo_input, char *cadena, char *alfabeto, char *clave, char accion, FILE *salida)
  49. {
  50.    FILE *entrada = NULL;
  51.    unsigned long longitud,tam_bloque,tam_clave,tam_alfabeto;
  52.    char *lector,*busqueda;
  53.    int *desplazamiento,i,indice = 0;
  54.  
  55.    /* comprobamos que en alfabeto no haya letras repetidas */
  56.    for(i = 0 ; alfabeto[i] ; i++)
  57.        if(strchr(alfabeto + i + 1,alfabeto[i]))
  58.            return 0;
  59.  
  60.    /* comprobamos que los caractreres de la clave esten en el alfabeto */
  61.    for(i = 0 ; clave[i] ; i++)
  62.        if(!strchr(alfabeto,clave[i]))
  63.            return 0;
  64.  
  65.    if(modo_input == IN_CADENA)
  66.        longitud = strlen(cadena);
  67.    else if(modo_input == IN_FICHERO)
  68.    {
  69.        if(!(entrada = fopen(cadena,"rb")))
  70.            return 0;
  71.  
  72.        longitud = flen(entrada);
  73.    }
  74.    else
  75.        return 0;
  76.  
  77.    tam_alfabeto = strlen(alfabeto);
  78.    tam_clave = tam_bloque = strlen(clave);
  79.  
  80.    if(!(lector = malloc(tam_bloque * sizeof(char))))
  81.        return 0;
  82.  
  83.    if(!(desplazamiento = malloc(tam_bloque * sizeof(int))))
  84.    {
  85.        free(lector);
  86.        return 0;
  87.    }
  88.  
  89.    for(i = 0 ; clave[i] ; i++)
  90.    {
  91.        if(!(busqueda = strchr(alfabeto,clave[i])))
  92.        {
  93.            free(lector);
  94.            free(desplazamiento);
  95.  
  96.            return 0;
  97.        }
  98.  
  99.        if(accion == ACCION_CIFRAR)
  100.            desplazamiento[i] = busqueda - alfabeto;
  101.        else if(accion == ACCION_DESCIFRAR)
  102.            desplazamiento[i] = alfabeto - busqueda; /* el desplazamiento de descifrado es el opuesto del de cifrado */
  103.        else
  104.        {
  105.            free(lector);
  106.            free(desplazamiento);
  107.  
  108.            return 0;
  109.        }
  110.    }
  111.  
  112.    if(modo_input == IN_CADENA)
  113.    {
  114.        while(longitud)
  115.        {
  116.            if(longitud < tam_bloque)
  117.                tam_bloque = longitud;
  118.  
  119.            memcpy(lector,cadena,tam_bloque * sizeof(char));
  120.  
  121.            for(i = 0 ; i < tam_bloque ; i++)
  122.            {
  123.                if(busqueda = strchr(alfabeto,lector[i]))
  124.                {
  125.                    lector[i] = alfabeto[((busqueda - alfabeto) + desplazamiento[indice] + tam_alfabeto) % tam_alfabeto];
  126.                    indice = (indice + 1) % tam_clave;
  127.                }
  128.            }
  129.  
  130.            fwrite(lector , tam_bloque*sizeof(char) , 1 , salida);
  131.  
  132.            if((tam_bloque == tam_clave) && (longitud > tam_bloque))
  133.                cadena += tam_bloque;
  134.  
  135.            longitud -= tam_bloque;
  136.        }
  137.    }
  138.    else if(modo_input == IN_FICHERO)
  139.    {
  140.        while(longitud)
  141.        {
  142.            if(longitud < tam_bloque)
  143.                tam_bloque = longitud;
  144.  
  145.            fread(lector,tam_bloque * sizeof(char),1,entrada);
  146.  
  147.            for(i = 0 ; i < tam_bloque ; i++)
  148.            {
  149.                if(busqueda = strchr(alfabeto,lector[i]))
  150.                {
  151.                    lector[i] = alfabeto[((busqueda - alfabeto) + desplazamiento[indice] + tam_alfabeto) % tam_alfabeto];
  152.                    indice = (++indice) % tam_clave;
  153.                }
  154.            }
  155.  
  156.            fwrite(lector , tam_bloque*sizeof(char) , 1 , salida);
  157.  
  158.            longitud -= tam_bloque;
  159.        }
  160.    }
  161.    else
  162.    {
  163.        if(entrada)
  164.            fclose(entrada);
  165.  
  166.        free(lector);
  167.        free(desplazamiento);
  168.  
  169.        return 0;
  170.    }
  171.  
  172.    if(entrada)
  173.        fclose(entrada);
  174.  
  175.    free(lector);
  176.    free(desplazamiento);
  177.  
  178.    return 1;
  179. }
  180.  
  181. int main(int argc, char *argv[])
  182. {
  183.    char error[] = "%s [+|-]c (cifrar|descifrar) -a alfabeto -[s|f] [cadena|fichero] -k clave -o [fichero_salida|std]\n";
  184.    char alfabeto[MAX_STRLEN] = "", fentrada[MAX_STRLEN] = "", clave[MAX_STRLEN] = "", fsalida[MAX_STRLEN] = "";
  185.    char *texto = NULL,*ftemp = NULL;
  186.    int sobreescribir = 0, modo = ACCION_CIFRAR + ACCION_DESCIFRAR + 1, i, j;
  187.    FILE *f;
  188.  
  189.    if(argc != 10)
  190.    {
  191.        fprintf(stderr,error,argv[0]);
  192.        return 1;
  193.    }
  194.  
  195.    for(i = 1 ; i < 10 ; i += 2)
  196.    {
  197.        if(!strcmp(argv[i],"-a"))
  198.        {
  199.            if(strlen(alfabeto))
  200.            {
  201.                fprintf(stderr,"-a: Parametro repetido\n");
  202.                return 2;
  203.            }
  204.  
  205.            if(!strlen(argv[i + 1]))
  206.            {
  207.                fprintf(stderr,"-a: Alfabeto vacio no permitido\n");
  208.                return 3;
  209.            }
  210.  
  211.            for(j = 0 ; argv[i + 1][j] ; j++)
  212.            {
  213.                if(strchr(argv[i + 1] + j + 1, argv[i + 1][j]))
  214.                {
  215.                    fprintf(stderr,"-a: No se permiten caracteres repetidos en el alfabeto\n");
  216.                    return 4;
  217.                }
  218.            }
  219.  
  220.            if(strlen(argv[i + 1]) >= MAX_STRLEN)
  221.            {
  222.                fprintf(stderr,"-a: El alfabeto es demasiado largo. Se truncara a partir del caracter %d.\n",MAX_STRLEN);
  223.  
  224.                strncpy(alfabeto, argv[i + 1], 255);
  225.                alfabeto[255] = '\0';
  226.            }
  227.            else
  228.                strcpy(alfabeto,argv[i + 1]);
  229.        }
  230.        else if(!strcmp(argv[i],"-s"))
  231.        {
  232.            if(texto || strlen(fentrada))
  233.            {
  234.                fprintf(stderr,"-s: Parametro -[s|f] repetido\n");
  235.                return 5;
  236.            }
  237.  
  238.            texto = argv[i + 1];
  239.        }
  240.        else if(!strcmp(argv[i],"-f"))
  241.        {
  242.            if(texto || strlen(fentrada))
  243.            {
  244.                fprintf(stderr,"-f: Parametro -[s|f] repetido\n");
  245.                return 6;
  246.            }
  247.  
  248.            if(strlen(argv[i + 1]) >= MAX_STRLEN)
  249.            {
  250.                fprintf(stderr,"-f: El nombre del fichero de entrada no debe exceder los %d caracteres\n",MAX_STRLEN);
  251.                return 7;
  252.            }
  253.  
  254.            if(!strlen(argv[i + 1]))
  255.            {
  256.                fprintf(stderr,"-f: El nombre del fichero de entrada no puede estar vacio\n");
  257.                return 8;
  258.            }
  259.  
  260.            strcpy(fentrada,argv[i + 1]);
  261.        }
  262.        else if(!strcmp(argv[i],"-k"))
  263.        {
  264.            if(strlen(clave))
  265.            {
  266.                fprintf(stderr,"-k: Parametro -k repetido\n");
  267.                return 9;
  268.            }
  269.  
  270.            if(!strlen(argv[i + 1]))
  271.            {
  272.                fprintf(stderr,"-k: No se permiten claves vacias");
  273.                return 10;
  274.            }
  275.  
  276.            if(strlen(argv[i + 1]) >= MAX_STRLEN)
  277.            {
  278.                fprintf(stderr,"-k: La clave no debe exceder los %d caracteres\n",MAX_STRLEN);
  279.                return 11;
  280.            }
  281.  
  282.            if(!strlen(argv[i + 1]))
  283.            {
  284.                fprintf(stderr,"-k: La clave no puede ser vacia\n");
  285.                return 12;
  286.            }
  287.  
  288.            strcpy(clave,argv[i + 1]);
  289.        }
  290.        else if(!strcmp(argv[i],"-o"))
  291.        {
  292.            if(strlen(fsalida))
  293.            {
  294.                fprintf(stderr,"-o: Parametro -o repetido\n");
  295.                return 13;
  296.            }
  297.  
  298.            if(strlen(argv[i + 1]) >= MAX_STRLEN)
  299.            {
  300.                fprintf(stderr,"-o: El nombre del fichero de salida no debe exceder los %d caracteres\n",MAX_STRLEN);
  301.                return 14;
  302.            }
  303.  
  304.            if(!strlen(argv[i + 1]))
  305.            {
  306.                fprintf(stderr,"-o: El nombre del fichero de salida no puede estar vacio\n");
  307.                return 15;
  308.            }
  309.  
  310.            strcpy(fsalida,argv[i + 1]);
  311.        }
  312.        else if(!strcmp(argv[i],"-c"))
  313.        {
  314.            if(!(modo ^ ACCION_CIFRAR) || !(modo ^ ACCION_DESCIFRAR))
  315.            {
  316.                fprintf(stderr,"-c: Parametro [+|-]c repetido\n");
  317.                return 16;
  318.            }
  319.  
  320.            modo = ACCION_DESCIFRAR;
  321.            i--; /* este argumento no tiene asociado un parametro */
  322.        }
  323.        else if(!strcmp(argv[i],"+c"))
  324.        {
  325.            if(!(modo ^ ACCION_CIFRAR) || !(modo ^ ACCION_DESCIFRAR))
  326.            {
  327.                fprintf(stderr,"+c: Parametro [+|-]c repetido\n");
  328.                return 17;
  329.            }
  330.  
  331.            modo = ACCION_CIFRAR;
  332.            i--; /* este argumento no tiene asociado un parametro */
  333.        }
  334.        else
  335.        {
  336.            fprintf(stderr,error,argv[0]);
  337.            return 18;
  338.        }
  339.    }
  340.  
  341.    //comprobar que los caracteres de la clave estan en el alfabeto
  342.    for(i = 0 ;  clave[i] ; i++)
  343.    {
  344.        if(!strchr(alfabeto,clave[i]))
  345.        {
  346.            fprintf(stderr,"La clave contiene caracteres que no aparecen en el alfabeto\n");
  347.            return 19;
  348.        }
  349.    }
  350.  
  351.    if(!strcmp(fsalida,"std"))
  352.    {
  353.        f = stdout;
  354.    }
  355.    else
  356.    {
  357.        if(f = fopen(fsalida,"r"))
  358.        {
  359.            char opcion;
  360.  
  361.            do{
  362.                printf("El fichero de salida ya existe. Deseas sobreescribirlo? (S/N) ");
  363.                opcion = getchar();
  364.  
  365.                if(opcion > 'Z')
  366.                    opcion += 'S' - 's';
  367.  
  368.                while(getchar() != '\n');
  369.  
  370.            }while(opcion!= 'S' && opcion!='N');
  371.  
  372.            if(opcion == 'S')
  373.            {
  374.                fclose(f);
  375.  
  376.                ftemp = tmpnam(NULL);
  377.  
  378.                if(!(f = fopen(ftemp,"wb")))
  379.                {
  380.                    fprintf(stderr,"%s: Error al abrir el fichero de salida\n",argv[0]);
  381.                    return 20;
  382.                }
  383.                sobreescribir = 1;
  384.            }
  385.            else
  386.            {
  387.                fclose(f);
  388.                return 0;
  389.            }
  390.        }
  391.        else
  392.            f = fopen(fsalida,"wb");
  393.    }
  394.  
  395.    //si fsalida == std llamar a vigenere con los parametro y fsalida stdout
  396.    if(texto)
  397.    {
  398.        if(!vigenere(IN_CADENA,texto,alfabeto,clave,modo,f))
  399.        {
  400.            fprintf(stderr,"%s no ha podido cifrar la informacion dada\n",argv[0]);
  401.            return 21;
  402.        }
  403.    }
  404.    else
  405.    {
  406.        if(!vigenere(IN_FICHERO,fentrada,alfabeto,clave,modo,f))
  407.        {
  408.            fprintf(stderr,"%s no ha podido cifrar la informacion dada\n",argv[0]);
  409.            return 21;
  410.        }
  411.    }
  412.  
  413.    if(strcmp(fsalida,"std"))
  414.        fclose(f);
  415.  
  416.    if(sobreescribir)
  417.    {
  418.        remove(fentrada);
  419.        rename(ftemp,fentrada);
  420.        remove(ftemp);
  421.    }
  422.  
  423.    return 0;
  424. }
  425.  

Sintaxis (mi programa se llama vigenere.exe):
Código:
vigenere [+|-]c (cifrar|descifrar) -a alfabeto -[s|f] [cadena|fichero] -k clave -o [fichero_salida|std]

+c cifrar
-c descifrar

-a "alfabeto de cifrado": Los caracteres que se consideraran para cifrar.

-s "cadena": La entrada es la cadena que sigua a -s
-f "fichero": La entrada se tomara del nombre de fichero que siga a -f

-k "clave": Indicara el desplazamiento de los caracteres del texto en claro

-o "fichero": La salida se producira en el fichero indicado.
-o std: La salida se producira por pantalla.

Ejemplos:
Código:
vigenere +c -a "abcdefghijklmnopqrstuvwxyz .:,;-+" -s "el simbolo de la suma es + y el de la resta -" -k "ejemplo de clave" -o std

iu;;xxphostfp +e;.yypesl,dt ee+;hn;xpe-;vx :j


vigenere +c -a "abcdefghijklmnopqrstuvwxyz .:,;-+" -s "el simbolo de la suma es + y el de la resta -" -k "ejemplo de clave" -o prueba.txt

type prueba.txt
iu;;xxphostfp +e;.yypesl,dt ee+;hn;xpe-;vx :j


vigenere -c -a "abcdefghijklmnopqrstuvwxyz .:,;-+" -s "iu;;xxphostfp +e;.yypesl,dt ee+;hn;xpe-;vx :j" -k "ejemplo de clave" -o std

el simbolo de la suma es + y el de la resta -

vigenere -c -a "abcdefghijklmnopqrstuvwxyz .:,;-+" -f prueba.txt -k "ejemplo de clave" -o std

el simbolo de la suma es + y el de la resta -

El orden de los argumentos no tiene que ser el que he utilizado yo, puede ser cualquier otro.

¡Saludos!

PD:

El codigo ensablador que ha dejado cpu2 sigue la sintaxis Intel. GCC utiliza sintaxis AT&T (creo).

cpu2, ¿podrías traducir tu código de Intel a AT&T?
« Última modificación: 23 Junio 2013, 08:37 am por do-while » En línea

- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!
erest0r

Desconectado Desconectado

Mensajes: 147



Ver Perfil
Re: Como cifrar letra por letra en C++
« Respuesta #67 en: 23 Agosto 2013, 05:32 am »

No soy tan experto como uds pero siguiendo la regla del cifrado de Cesar logre hacer mi codigo asi:

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

int main(){
    char oracion[100];
    char codificado[100];
    int i, desp;
    for(i = 0; i < 100; i++)
        codificado[i] = '\0';
    printf("Ingrese una oracion para cifrar:\n");
    fgets(oracion, 100, stdin);
    do{
        printf("Ingrese el numero de desplazamientos en el abecedario: ");
        scanf("%d", &desp);
        if(desp > 27)
            printf("El desplazamiento no puede ser mayor a 27\n\n");
    }
    while(desp > 27);
    for(i = 0; i < strlen(oracion); i++){
        if(oracion[i] >= 65 && oracion[i] <= 90){
            if(oracion[i] + desp > 90)
                codificado[i] = (oracion[i] - 90) + desp + 64;
            else
                codificado[i] = oracion[i] + desp;
        }
        else{
            if(oracion[i] >= 97 && oracion[i] <=122){
                if(oracion[i] + desp > 122)
                    codificado[i] = (oracion[i] - 122) + desp + 96;
                else
                    codificado[i] = oracion[i] + desp;
            }
            else
                codificado[i] = oracion[i];
        }
    }
    printf("La oracion codificada es: %s", codificado);
    getchar();
    return 0;
}

EDIT: Olvide inicializar el array "codificado"  ;D
« Última modificación: 23 Agosto 2013, 06:05 am por erest0r » En línea

Cruzar la calle junto a mucha gente cuando el semáforo sigue en rojo da seguridad y espíritu de equipo... o cruzamos todos o morimos juntos.
Páginas: 1 2 3 4 5 6 [7] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Codificacion en archivos bat, letra ñ
Scripting
santi810 3 12,239 Último mensaje 1 Diciembre 2013, 18:57 pm
por Eleкtro
[DUDA] Como Desactivar Dispositivos Portátiles Para Que Se Le Asigne Una Letra
Windows
KZN 3 2,916 Último mensaje 11 Marzo 2014, 17:00 pm
por Randomize
Dibujar letra 'T'
PHP
luchi 2 2,387 Último mensaje 20 Abril 2014, 22:14 pm
por luchi
Como con una letra direccionarme a la tabla/registro?
Programación C/C++
enzopaez14 1 2,109 Último mensaje 5 Septiembre 2016, 02:50 am
por AlbertoBSD
Comparar letra una letra en un array, con una letra del abcdario
Programación C/C++
Naimaderis 2 3,964 Último mensaje 10 Marzo 2017, 04:24 am
por Naimaderis
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines