Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Royca3 en 10 Junio 2013, 06:31 am



Título: Como cifrar letra por letra en C++
Publicado por: Royca3 en 10 Junio 2013, 06:31 am
Hola amigos bueno se me ha pasado por la cabeza la idea de crear una forma de cifrar letras y números :D pues bueno ya he creado la forma de cifrado pero no quise quedarme en esto nada mas pensé en hacer un programa que me pidiera una palabra o una frase y que la ecripte, pero los únicos comandos que me sabia eran los de la Shell X’D pues decidí leer un poco sobre C++, Bueno y de lectura en lectura me ayudaron con lo siguiente :

Código:
#include<stdio.h> 
#include<conio.h>
#include<dos.h>
void main(void)
{
printf("Ingrese la palabra: ");
scanf("%s");
char cad[10]="%s";
clrscr();
for(int a=0;a<10;a++)
{
printf("%c\n",cad[a]);
}
getch();
}


Pero el código no realiza la función que yo quiero (aclaro hay lo único que hace es pedirle al usuario que ingrese una palabra y la separe letra por letra)  pero esa no es mi meta si alguien podría ayudarme con esto le agradecería sinceramente.

Saludos.   :laugh:


Título: Re: Como cifrar letra por letra en C++
Publicado por: amchacon en 10 Junio 2013, 07:49 am
Código
  1. #include<stdio.h>
  2.  
  3. int main()
  4. {
  5.  char Palabra[256];
  6.  int i = 0;
  7.  fgets (Palabra,255,stdin);
  8.  
  9.  for  (i = 0; i < strlen(Palabra);i++)
  10.       printf("%c \n",Palabra[i]);
  11.  
  12.  getchar(); // pausa
  13.  getchar();
  14.  
  15.  return 0;
  16. }

Has cumplido varias violaciones a la norma (void main, librería conio,dos y uso de getch()).


Título: Re: Como cifrar letra por letra en C++
Publicado por: leosansan en 10 Junio 2013, 08:19 am
Cita de: Royca3 link=topic=392162.msg1859787#msg1859787

Pero el código no realiza la función que yo quiero (aclaro hay lo único que hace es pedirle al usuario que ingrese una palabra y la separe letra por letra)  pero esa no es mi meta si alguien podría ayudarme con esto le agradecería sinceramente.


¿Y que más querías que hiciera?. El código hace ni más ni menos lo que tú le has implementado y, lo único que has hecho es imprimir una cadena introducida por teclado,  ¿crees que te adivina el pensamiento y "él" añade el resto del código?. Y aún el caso de imprimir la cadena es aventurado, toda vez que presupones que el usuario va a introducir una cadena de justitos diez caracteres. Mejor sería:

Código
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. int main(void)
  4. {
  5.    int i=0;
  6.    char cadena[10];
  7.    printf("Ingrese la palabra: ");
  8.    scanf("%10s",&cadena);
  9.    for(i=0;cadena[i]!='\0';i++)
  10.        printf("%c ",cadena[i]);
  11.    getchar();
  12.    return 0;
  13. }


De esta manera te aseguras "tomar" sólo diez caracteres.

Además de lo comentado por amchacon te aconsejaría leer algo sobre el tema de cifrado.

Si estas empezando te diría que te mires el cifrado de César (http://es.wikipedia.org/wiki/Cifrado_C%C3%A9sar), así para empezar con uno sencillo.


Saluditos! .... ..
(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)

P.D: amchacon ,te faltó en el código la librería string.h para hacer uso de strlen. Sí, ya sé que son las prisas. A esta hora y ya estamos como motos  ;)  ;)


Título: Re: Como cifrar letra por letra en C++
Publicado por: daryo en 10 Junio 2013, 16:56 pm
aca tienes un ejemplo en c++  :D

cifrar.cpp
Código
  1. #include <iostream>
  2. #include <string>
  3.  
  4. using namespace std;
  5.  
  6. int main()
  7. {
  8.    string frase;
  9.    cout << "escriba una frase" << endl;
  10.    getline(cin,frase);
  11.    int n=1;
  12.    for(int tamano=0;tamano<frase.size();tamano++)
  13.    {
  14.        char letra=frase[tamano]+n;
  15.        cout << letra;
  16.        n++;
  17.        if(n>10)
  18.        {
  19.            n=1;
  20.        }
  21. }
  22.  
descifrar.cpp
Código
  1. #include <iostream>
  2. #include <string>
  3.  
  4. using namespace std;
  5.  
  6. int main()
  7. {
  8.    string frase;
  9.    cout << "escriba una frase cifrada" << endl;
  10.    getline(cin,frase);
  11.    int n=1;
  12.    for(int tamano=0;tamano<frase.size();tamano++)
  13.    {
  14.        char letra=frase[tamano]-n;
  15.        cout << letra;
  16.        n++;
  17.        if(n>10)
  18.        {
  19.            n=1;
  20.        }
  21.    }
  22. }
  23.  


Título: Re: Como cifrar letra por letra en C++
Publicado por: leosansan en 10 Junio 2013, 18:56 pm
aca tienes un ejemplo en c++  :D

Y aquí uno en C:

Código
  1. #include<stdio.h>
  2.  
  3. int main()
  4. {
  5.    char Palabra[256];
  6.    int i = 0;
  7.    puts ("\Introduzca palabra o frase a cifrar:");
  8.    fgets (Palabra,255,stdin);
  9.    puts ("\nLa frase es:");
  10.    for  (i = 0;Palabra[i]!='\0';i++)
  11.       printf("%c ",Palabra[i]);
  12.    puts ("\nCiframos la frase");
  13.    for  (i = 0; Palabra[i]!='\0';i++)
  14.       {
  15.           Palabra[i]+=i;
  16.           printf("%c ",Palabra[i]);
  17.       }
  18.    puts ("\n\nDesiframos la frase");
  19.    for  (i = 0; Palabra[i]!='\0';i++)
  20.       {
  21.           Palabra[i]-=i;
  22.           printf("%c ",Palabra[i]);
  23.       }
  24.    puts ("\n\nPresione ENTER para salir");
  25.    getchar();
  26.    return 0;
  27. }
  28.  


Saluditos! .... ..(http://st.forocoches.com/foro/images/smilies/simba2.gif)


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 10 Junio 2013, 19:47 pm
Y aquí uno en C:

Código
  1. #include<stdio.h>
  2.  
  3. int main()
  4. {
  5.    char Palabra[256];
  6.    int i = 0;
  7.    puts ("\Introduzca palabra o frase a cifrar:");
  8.    fgets (Palabra,255,stdin);
  9.    puts ("\nLa frase es:");
  10.    for  (i = 0;Palabra[i]!='\0';i++)
  11.       printf("%c ",Palabra[i]);
  12.    puts ("\nCiframos la frase");
  13.    for  (i = 0; Palabra[i]!='\0';i++)
  14.       {
  15.           Palabra[i]+=i;
  16.           printf("%c ",Palabra[i]);
  17.       }
  18.    puts ("\n\nDesiframos la frase");
  19.    for  (i = 0; Palabra[i]!='\0';i++)
  20.       {
  21.           Palabra[i]-=i;
  22.           printf("%c ",Palabra[i]);
  23.       }
  24.    puts ("\n\nPresione ENTER para salir");
  25.    getchar();
  26.    return 0;
  27. }
  28.  


Saluditos! .... ..(http://st.forocoches.com/foro/images/smilies/simba2.gif)

Muchas gracias a todos y perdón por mi ignorancia....  :-X
Bueno Te agradezco a ti leosansan Este Programa era el que buscaba...
 ;D

Saludos.
(Excelente Foro ;)


Título: Re: Como cifrar letra por letra en C++
Publicado por: daryo en 10 Junio 2013, 20:03 pm

(Excelente Foro ;)
si que lo es  ;D


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 10 Junio 2013, 20:57 pm
si que lo es  ;D

 ;-)  ;-)  ;-)

Soy nuevo y ya me encanto xD


Título: Re: Como cifrar letra por letra en C++
Publicado por: Puntoinfinito en 10 Junio 2013, 21:00 pm
Aquí otro ejemplo caesar:

Código
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. int main() {
  6.  
  7.    string palabra = ""; //Creamos e inicalizamos variables
  8.    int numero = 0;
  9.    int TamanyoPalabra = 0;
  10.  
  11.    cout << "Palabra? >> "; cin >> palabra;  // 1  i  2 paso
  12.    cout << "Veces a correr >> "; cin >> numero;  // 3 paso
  13.  
  14.    TamanyoPalabra = palabra.length(); // 4 paso
  15.  
  16.    for (int i = 0; i < TamanyoPalabra ; i++) { // 4 paso
  17.        for (int z = 0; z < numero; z++) { palabra[i]++; } // 5 paso
  18.    } // 6 paso
  19.  
  20.    cout << palabra; // Mostrar palabra cifrada
  21.  
  22.    return 0; //Salir
  23.  
  24. }

FUENTE Y MÁS INFORMACIÓN DEL CODE: http://www.infiniterware.net/tutoriales/programacion-general/Caesar-cipher-C++.html

Saluuuuuuu2


Título: Re: Como cifrar letra por letra en C++
Publicado por: leosansan en 10 Junio 2013, 21:51 pm
Aquí otro ejemplo caesar:

Pues no, ni el tuyo ni el de daryo ni el mío con cifrados tipo César, al menos como yo veo los códigos.

Yo lo que hice en el post fue sugerirle que lo mirará pero no dije que en mi código lo aplicará. Me fui, como daryo, a lo fácil que es incrementar la variable letra sencillamente, mientras que en el cifrado César hay que tener en cuenta que si se llega a la las letras finales del abecedario se cuentan las últimas y, si faltan, se sigue la suma por las primeras.

Más información en Cifrado César cortesía de Wikipedia (http://es.wikipedia.org/wiki/Cifrado_C%C3%A9sar).


Saluditos! .... ..(http://st.forocoches.com/foro/images/smilies/ciao.gif)


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 10 Junio 2013, 22:10 pm
Gracias amigo pero me confundí yo utilizo C  :) Pero bueno, oye Como le hago para que coja la palabra que el usuario ingresa y la cambie por otras letras (especificadas por mi) Gracias

Saludos.


Título: Re: Como cifrar letra por letra en C++
Publicado por: cypascal en 10 Junio 2013, 22:46 pm
Aquí te dejo el que hice yo en su día, que trabaja con ficheros de texto. Se puede seleccionar el paso del cifrado, y tiene en cuenta que que cuando se llega a la Z se tiene que volver a empezar por la A.

También está en esta dirección:
http://cypascal.blogspot.com.es/2013/04/cifrado-cesar-en-c.html (http://cypascal.blogspot.com.es/2013/04/cifrado-cesar-en-c.html)


Código:
/*CIFRADO CESAR EN C/C++*/

/*Este programa se va a usar para llevar a cabo una codificación de un fichero
de texto, mediante el codificado CESAR, que es uno de los métodos más simples
de cifrar.
La variable trans==translación de cifrado, es la que indica cuantas letras
se va a correr el abecedario hacia la derecha. Ejemplo:
      trans=3
      c1=Caracter decodificado
      c2=Caracter codificado
      c2=c1+trans
      Entonces en nuestro caso si c1='A'
      c2='A'+3='D'

El programa solo codifica letras, tanto mayúsculas como minúsculas:
del ASCII 65 ('A') al 90 ('Z') y del 97 ('a') al 122 ('z').
*/

#include <stdio.h>
#include <string.h>

int main(void)
{
 FILE *dat1,*dat2;
 char nombre1[50],nombre2[50],c;
 int trans;
 
 printf("Seleccione translacion de encriptacion: "); scanf("%d", &trans);
 printf("Nombre del fichero a codificar: "); scanf("%s", &nombre1);
 printf("Nombre del fichero donde guardar codificado: "); scanf("%s", &nombre2);
 
 
 if (fopen(nombre1,"r")==NULL)
  printf("\nEl fichero no existe.\n\n");
 else
    {
  dat1=fopen(nombre1,"r");/*Se abre en modo lectura*/
  dat2=fopen(nombre2,"w");/*Se abre en modo escritura*/
  fscanf(dat1,"%c",&c);
  while (!feof(dat1))
  {
   /*Se codifica el caracter*/
   if ((c>='A')&&(c<='Z'))
   {
                c=((c+trans-'A')%('Z'-'A'+1))+'A';           
            }
            else if ((c>='a')&&(c<='z'))
            {
                c=(c+trans-'a')%('z'-'a'+1)+'a';
            }
           
   /*Se escribe el caracter en el codificado*/
   fprintf(dat2,"%c",c);
   
   /*Se lee un nuevo caracter*/
   fscanf(dat1,"%c",&c);
  }
  fclose(dat1);
  fclose(dat2);/*Se cierran ambos ficheros*/
 }
}

Salu10 y bienvenido


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 10 Junio 2013, 23:13 pm
Aquí te dejo el que hice yo en su día, que trabaja con ficheros de texto. Se puede seleccionar el paso del cifrado, y tiene en cuenta que que cuando se llega a la Z se tiene que volver a empezar por la A.

También está en esta dirección:
http://cypascal.blogspot.com.es/2013/04/cifrado-cesar-en-c.html (http://cypascal.blogspot.com.es/2013/04/cifrado-cesar-en-c.html)


Código:
/*CIFRADO CESAR EN C/C++*/

/*Este programa se va a usar para llevar a cabo una codificación de un fichero
de texto, mediante el codificado CESAR, que es uno de los métodos más simples
de cifrar.
La variable trans==translación de cifrado, es la que indica cuantas letras
se va a correr el abecedario hacia la derecha. Ejemplo:
      trans=3
      c1=Caracter decodificado
      c2=Caracter codificado
      c2=c1+trans
      Entonces en nuestro caso si c1='A'
      c2='A'+3='D'

El programa solo codifica letras, tanto mayúsculas como minúsculas:
del ASCII 65 ('A') al 90 ('Z') y del 97 ('a') al 122 ('z').
*/

#include <stdio.h>
#include <string.h>

int main(void)
{
 FILE *dat1,*dat2;
 char nombre1[50],nombre2[50],c;
 int trans;
 
 printf("Seleccione translacion de encriptacion: "); scanf("%d", &trans);
 printf("Nombre del fichero a codificar: "); scanf("%s", &nombre1);
 printf("Nombre del fichero donde guardar codificado: "); scanf("%s", &nombre2);
 
 
 if (fopen(nombre1,"r")==NULL)
  printf("\nEl fichero no existe.\n\n");
 else
    {
  dat1=fopen(nombre1,"r");/*Se abre en modo lectura*/
  dat2=fopen(nombre2,"w");/*Se abre en modo escritura*/
  fscanf(dat1,"%c",&c);
  while (!feof(dat1))
  {
   /*Se codifica el caracter*/
   if ((c>='A')&&(c<='Z'))
   {
                c=((c+trans-'A')%('Z'-'A'+1))+'A';           
            }
            else if ((c>='a')&&(c<='z'))
            {
                c=(c+trans-'a')%('z'-'a'+1)+'a';
            }
           
   /*Se escribe el caracter en el codificado*/
   fprintf(dat2,"%c",c);
   
   /*Se lee un nuevo caracter*/
   fscanf(dat1,"%c",&c);
  }
  fclose(dat1);
  fclose(dat2);/*Se cierran ambos ficheros*/
 }
}

Salu10 y bienvenido


Este code lo que hace es buscar un archivo y "encriptarlo" verdad?
Lo que yo necesito es un programa que pida una palabra o frase y que cambie las letras ejemplo A por H b por X y asi entiendes?

Pero igual Gracias

saludos.


Título: Re: Como cifrar letra por letra en C++
Publicado por: cypascal en 10 Junio 2013, 23:20 pm
Ups!, perdón, pensaba que estábamos con Cesar.
Pero no me queda claro, ¿Qé método de cifrado quieres utilizar?

Salu10


Título: Re: Como cifrar letra por letra en C++
Publicado por: CCross en 10 Junio 2013, 23:28 pm
Buenas amigos!!

Aqui otra versión del cifrado cesar donde tu puedes indicar el desplazamiento que quieras

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main()
  5. {
  6.     int des, i = 0, j = 0;
  7.     char cadena[30] = {0};
  8.  
  9.     printf("Introduce una cadena: ");
  10.     scanf("%s", cadena);
  11.  
  12.     printf("Ingrese desplazamiento: ");
  13.     scanf(" %d", &des);
  14.  
  15.     for(; cadena[i]!='\0'; i++)
  16.        cadena[i]+=des;
  17.     printf("\nEncriptado es: %s \n", cadena);
  18.  
  19.     for(; cadena[j]!='\0'; j++)
  20.        cadena[j]-=des;
  21.      printf("\nDesencriptado es: %s \n", cadena);
  22.  
  23.     return 0;
  24. }

Saludos  ;D


Título: Re: Como cifrar letra por letra en C++
Publicado por: amchacon en 10 Junio 2013, 23:32 pm
Código
  1. for(; cadena[i]!='\0'; i++)
  2.        cadena[i]+=des;
  3.  
  4. printf("\nEncriptado es: %s \n", cadena);
  5.  
  6. for(; cadena[j]!='\0'; j++)
  7.        cadena[j]-=des;
  8. printf("\nDesencriptado es: %s \n", cadena);

Y digo yo, que necesidad hay de hacer el caso y el inverso:

Código
  1. char cadena_aux[30];
  2.  
  3. for(; cadena[i]!='\0'; i++)
  4. {
  5.        cadena[i]+=des;
  6.        cadena_aux[i] = cadena[i];
  7. }
  8. cadenaaux[i] = '\0';
  9.  
  10. printf("\nEncriptado es: %s  y descifrado es %s\n", cadena,cadena_aux);
  11.  


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 11 Junio 2013, 00:00 am
Bueno Alguien que me explique algo  :(
El código de leosansan pero necesito que en lugar de ese método lo cambie por este:
A = X
B = J
C = O
D = P
E = Z
F = W
G = A
H = U
I = Ñ
J=L
K = D
L=Q
M=S
N = F
Ñ=R
O = B
P=M
Q=V
R=H
S=K
T = N
U=Y
V= T
W=I
X  = E
Y= G
Z = C


Título: Re: Como cifrar letra por letra en C++
Publicado por: CCross en 11 Junio 2013, 00:04 am
Y digo yo, que necesidad hay de hacer el caso y el inverso:

Pues para descifrar no y ademas la forma que propones no hace lo deseado ya que la cadena
ya la habias modificado previamente y luego asignas los valores atuales que son los cifrados a
la cadena auxiliar

Saludos  :silbar:


Título: Re: Como cifrar letra por letra en C++
Publicado por: cypascal en 11 Junio 2013, 00:05 am
usa case

salu10


Título: Re: Como cifrar letra por letra en C++
Publicado por: amchacon en 11 Junio 2013, 00:16 am
Pues para descifrar no y ademas la forma que propones no hace lo deseado ya que la cadena
ya la habias modificado previamente y luego asignas los valores atuales que son los cifrados a
la cadena auxiliar

Saludos  :silbar:
Huy es verdad  :rolleyes:

Habría que hacer la igualación antes  ;-)


Título: Re: Como cifrar letra por letra en C++
Publicado por: CCross en 11 Junio 2013, 01:11 am
Bueno Alguien que me explique algo  :(
El código de leosansan pero necesito que en lugar de ese método lo cambie por este:
A = X
B = J
C = O
D = P
.....................

Creo que seria mas o menos asi:

Código
  1. #include<stdio.h>
  2.  
  3. int main()
  4. {
  5.    char caracter[2][28] = { {"ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"},
  6.                             {"XJOPZWAUÑLDQSFRBMVHKNYTIEGC"} };
  7.    char cadena[30] = {0};
  8.    int i, j = 0, k = 0;
  9.  
  10.    printf("Ingrese una cadena en Mayuscula: ");
  11.    scanf("%s", cadena);
  12.  
  13.       for (; cadena[k]!='\0'; k++){
  14.           for (i = 0; i < 27; i++)
  15.               if (cadena[j] == caracter[0][i]){
  16.                   cadena[j] = caracter[1][i];
  17.                   j++;
  18.             }
  19.       }
  20.     printf("\n%s", cadena);
  21.  
  22.     return 0;
  23. }
  24.  

Saludos  ::)


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 11 Junio 2013, 01:13 am
Osea que? No se puede? o que debo hacer?
 :-X


Título: Re: Como cifrar letra por letra en C++
Publicado por: amchacon en 11 Junio 2013, 01:19 am
Osea que? No se puede? o que debo hacer?
 :-X
El método de Ccros funciona  ;)


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 11 Junio 2013, 01:37 am
Bueno compilo el código y tiene cero errores  ;-)
Pero a lo que lo ejecuto e ingreso la palabra a cifrar
se sale automáticamente, luego ingreso nuevamente y me aparecen los resultados pero solo cambia la primer letra las demás las deja iguales.
 
Saludos.


Título: Re: Como cifrar letra por letra en C++
Publicado por: CCross en 11 Junio 2013, 01:52 am
Bueno compilo el código y tiene cero errores  ;-)
Pero a lo que lo ejecuto e ingreso la palabra a cifrar
se sale automáticamente, luego ingreso nuevamente y me aparecen los resultados pero solo cambia la primer letra las demás las deja iguales.

He editado el codigo de arriba ahora hace los que deseas

Saludos  ;D


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 11 Junio 2013, 02:30 am
He editado el codigo de arriba ahora hace los que deseas

Saludos  ;D

Bueno mi amgo :D Gracias por tu interes...

Ahora me aprarece un error en
printf("\n%s", cadena);
 
     return 0;
}

Intentare compilarlo con el Dev-c++

Saludos.


Título: Re: Como cifrar letra por letra en C++
Publicado por: amchacon en 11 Junio 2013, 02:36 am
Bueno mi amgo :D Gracias por tu interes...

Ahora me aprarece un error en
printf("\n%s", cadena);
 
     return 0;
}

Intentare compilarlo con el Dev-c++

Saludos.
Es la línea 18 y es porque falta un punto y coma.

Te falta soltura en el lenguaje, yo te recomiendo que te lo mires entero.


Título: Re: Como cifrar letra por letra en C++
Publicado por: rir3760 en 11 Junio 2013, 03:11 am
En el cifrado de Cesar para encontrar los sustitutos puedes utilizar el operador de modulo (ya hay ejemplos) o bien se pueden colocar todos los caracteres en un array, con ello la operación termina como una suma (o resta si la operación es descifrar).

Por ejemplo:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define ABC  "abcdefghijklmnopqrstuvwxyz"
  5.  
  6. int main(void)
  7. {
  8.   char ch[] = ABC  ABC;
  9.   size_t max_despl = sizeof(ABC) - 1;
  10.   unsigned despl;
  11.   unsigned i;
  12.  
  13.   printf("Desplazamiento: ");
  14.   fflush(stdout);
  15.   if (scanf("%u", &despl) != 1 || despl > max_despl)
  16.      return EXIT_FAILURE;
  17.  
  18.   for (i = 0; i < max_despl; i++)
  19.      printf("%c ==> %c\n", ch[i], ch[i + despl]);
  20.  
  21.   return EXIT_SUCCESS;
  22. }

----

Lo que yo necesito es un programa que pida una palabra o frase y que cambie las letras ejemplo A por H b por X y asi entiendes?
Para eso debes colocar todos los caracteres a buscar en un array y sus sustituciones en otro, mas o menos así:
Código
  1. char  in[] = "Ab";
  2. char out[] = "HX";
Buscas cada carácter en el array "in" para conocer su indice, una vez lo obtienes (el indice, claro) lo sustituyes por el carácter correspondiente (mismo indice) del array "out".

La solución ya la tienes en el programa de CCross, una opción ligeramente distinta es utilizando la función strchr para realizar la búsqueda:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. int main(void)
  6. {
  7.   char  in[] = "ABCDEFGHIJKLMNÑOPQRSTUVWXYZ";
  8.   char out[] = "XJOPZWAUÑLDQSFRBMVHKNYTIEGC";
  9.   char cadena[30];
  10.   char *p;
  11.   int i;
  12.   int j;
  13.  
  14.   printf("Ingrese una cadena en Mayuscula: ");
  15.   fflush(stdout);
  16.   if (scanf("%s", cadena) != 1)
  17.      return EXIT_FAILURE;
  18.  
  19.   for (i = 0; cadena[i] != '\0'; i++){
  20.      p = strchr(in, cadena[i]);
  21.      putchar(p == NULL ? cadena[i] : out[p - in]);
  22.   }
  23.   putchar('\n');
  24.  
  25.   return EXIT_SUCCESS;
  26. }

Un saludo


Título: Re: Como cifrar letra por letra en C++
Publicado por: CCross en 11 Junio 2013, 03:29 am
Disculpa por el detallito lo que causa codedear a prisas, ya lo correji

Saludos  ;-)


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 11 Junio 2013, 03:48 am
rir3760 Muchas gracias el código es lo que buscaba pero obtengo el mismo error anterior el programa se me cierra antes de mostrar los resultados  :-( alguien sabe el porque?

(Gracias a TODOS)

Saludos.


Título: Re: Como cifrar letra por letra en C++
Publicado por: CCross en 11 Junio 2013, 03:56 am
rir3760 Muchas gracias el código es lo que buscaba pero obtengo el mismo error anterior el programa se me cierra antes de mostrar los resultados  :-( alguien sabe el porque

Prueba con poner un getchar(); antes de:

Código
  1. return EXIT_SUCCESS;

Buscate un buen libro de C te recomiendo el libro de kernighan y Ritchie que es muy bueno
para empezar

Saludos


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 11 Junio 2013, 04:57 am
Prueba con poner un getchar(); antes de:

Código
  1. return EXIT_SUCCESS;

Buscate un buen libro de C te recomiendo el libro de kernighan y Ritchie que es muy bueno
para empezar

Saludos


Igual se sale :'( Pues si de echo ya tengo unos manuales pero apenas comienzo :)
Pero porque se sigue saliendo del programa sin mostrar resultados?

Saludos.


Título: Re: Como cifrar letra por letra en C++
Publicado por: amchacon en 11 Junio 2013, 10:17 am
Igual se sale :'( Pues si de echo ya tengo unos manuales pero apenas comienzo :)
Pero porque se sigue saliendo del programa sin mostrar resultados?

Saludos.
Pon 2 getchar().

La razón por la que se sale esque el programa termina al finalizar el main, si que muestra los resultados pero va tan rápido que ni los ves.

Por cierto:
http://foro.elhacker.net/programacion_cc/iquestpor_que_no_deberias_usar_el_devcpp-t385150.0.html


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 11 Junio 2013, 21:11 pm
Pon 2 getchar().

La razón por la que se sale esque el programa termina al finalizar el main, si que muestra los resultados pero va tan rápido que ni los ves.

Por cierto:
http://foro.elhacker.net/programacion_cc/iquestpor_que_no_deberias_usar_el_devcpp-t385150.0.html

Listo amigo Todo en orden, el programa cumple la función requerida  ;-) ;-) ;-) ;-) Les agradezco a CCross, rir3760, a leosansan aunque le doy gracias a todos por su buena voluntad próxima mente subiré un tutorial  :laugh:

Saludos.


Título: Re: Como cifrar letra por letra en C++
Publicado por: leosansan en 12 Junio 2013, 16:58 pm
Buenas amigos!!

Aquí otra versión del cifrado cesar donde tu puedes indicar el desplazamiento que quieras


No es el cifrado César, te muestro una salida al código que planteas:


Citar
Introduce una cadena: wikipedia la enciclopedia libre
Ingrese desplazamiento:
cifrado es: ┘╦═╦ÊÃã╦├

descifrado es: wikipedia

Como ves, en el cifrado se "va más allá" de la z/Z, cuando debería empezar a contar desde la a.

Una solución  "a pura fuerza bruta", es decir aplicando estrictamente lo que plantea el cifrado César :


Código
  1. /*En criptografía, el cifrado César, también conocido como cifrado
  2. por desplazamiento, código de César o desplazamiento de César, es
  3. una de las técnicas de codificación más simples y más usadas.
  4. Es un tipo de cifrado por sustitución en el que una letra en el
  5. texto original es reemplazada por otra letra que se encuentra un
  6. número fijo de posiciones más adelante en el alfabeto. Por
  7. ejemplo, con un desplazamiento de 6.*/
  8. #include <stdio.h>
  9. #include<stdlib.h>
  10. #include <string.h>
  11. int main (void)
  12. {
  13.    int i,n=0,aux;
  14.    char frase [256];
  15.    char cadena []="WIKIPEDIA, LA ENCICLOPEDIA LIBRE \n\
  16.    Wikipedia la Enciclopedia Libre f F x X";
  17.    puts("WIKIPEDIA, LA ENCICLOPEDIA LIBRE \n\
  18.    Wikipedia la Enciclopedia Libre f F x X");
  19.    for (i=0;cadena[i]!='\0';i++)
  20.        {
  21.            if ((cadena [i]>='u' && cadena [i]<='z') || (cadena [i]>='U' && cadena [i]<='Z' ))   cadena [i]-=20;
  22.            else if (cadena [i]>='a' && cadena [i]<='t' || (cadena [i]>='A' && cadena [i]<='T' ))   cadena [i]+=6;
  23.        }
  24.    puts("\nY ahora codificada con desplazamiento 6:");
  25.    printf ("%s\n",cadena);
  26.    puts("\nY ahora descodificada: ");
  27.    for (i=0;cadena[i]!='\0';i++)
  28.        {
  29.            if ((cadena [i]<='f' && cadena [i]>='c') || (cadena [i]<='F' && cadena [i]>='C' ))   cadena [i]+=20;
  30.            else if (cadena [i]>'f' && cadena [i]<='z' || (cadena [i]>'F' && cadena [i]<='Z' ))   cadena [i]-=6;
  31.        }
  32.    printf ("%s\n",cadena);
  33.  
  34. /******* AHORA CON ENTRADA DESDE TECLADO *******/
  35.  
  36.    while (1)
  37.    {
  38.    n=0;
  39.    puts ("\n\nIntroduce una frase: ");
  40.    fgets (frase,255,stdin);
  41.    do
  42.    {
  43.        printf ("\nIndica el desplazamiento (1-25): ");
  44.        scanf ("%d",&n);
  45.        while (getchar()!='\n');
  46.    }while (n<1 || n>25);
  47.    for (i=0;frase[i]!='\0';i++)
  48.    {
  49.        if ((frase [i]>('z'-n) && frase [i]<='z') || (frase [i]>('Z'-n) && frase [i]<='Z' ))
  50.            frase [i]=frase [i]-26+n;
  51.        else if (frase [i]>='a' && frase [i]<=('z'-n) || (frase [i]>='A' && frase [i]<=('Z'-n) ))
  52.            frase [i]+=n;
  53.    }
  54.    printf("\nCodificada con desplazamiento %d \n",n);
  55.    printf ("%s\n",frase);
  56.    puts("\nY ahora descodificada: ");
  57.    for (i=0;frase[i]!='\0';i++)
  58.        {
  59.            if ((frase [i]<('a'+n) && frase [i]>=('a')) || (frase [i]<('A'+n) && frase [i]>=('A') ))
  60.            frase [i] =frase [i]+26-n;
  61.            else if ((frase [i]>=('a'+n) && frase [i]<=('z') )|| (frase [i]>=('A'+n) && frase [i]<=('Z') ))
  62.                frase [i]-=n;
  63.        }
  64.    printf ("%s\n",frase);
  65.    }
  66.  
  67.    /***************  :-)   OTRA FORMA  :-)   **********/
  68.    return 0;
  69. }
  70.  

Con una salida como esta:

Código
  1. WIKIPEDIA, LA ENCICLOPEDIA LIBRE
  2.    Wikipedia la Enciclopedia Libre f F x X
  3.  
  4. Y ahora codificada con desplazamiento 6:
  5. COQOVKJOG, RG KTIOIRUVKJOG ROHXK
  6.    Coqovkjog rg Ktioiruvkjog Rohxk l L d D
  7.  
  8. Y ahora descodificada:
  9. WIKIPEDIA, LA ENCICLOPEDIA LIBRE
  10.    Wikipedia la Enciclopedia Libre f F x X
  11.  
  12.  
  13. Introduce una frase:
  14. leosansan Abc Xyz
  15.  
  16. Indica el desplazamiento (1-25): 6
  17.  
  18. Codificada con desplazamiento 6
  19. rkuygtygt Ghi Def
  20.  
  21.  
  22. Y ahora descodificada:
  23. leosansan Abc Xyz

¡Vamos!, a ver si se animan a plantear códigos diferentes, que sean más ingeniosos y/o eficaces. Ya hay una media propuesta de cypascal usando la operación módulo -ver post anteriores-, aunque está incompleto, ya que le falto el descifrado. ;) ;-) ;)

Saluditos!.
     (http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Como cifrar letra por letra en C++
Publicado por: xv0 en 12 Junio 2013, 18:59 pm
Y que sucede si en mi cadena tengo algun caracter estilo " @#$*{}", la tabla ascii no es solo el abecedario.

Un saludo.


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 12 Junio 2013, 19:05 pm
leosansan, Excelente código, Gracias
(LA PROGRAMACIÓN ES MÁGICA  ;D ;D )

pd. Ya inicie a leer unas guías para aprender C

Saludos.


Título: Re: Como cifrar letra por letra en C++
Publicado por: CCross en 12 Junio 2013, 19:23 pm
No es el cifrado César, te muestro una salida al código que planteas:
Como ves, en el cifrado se "va más allá" de la z/Z, cuando debería empezar a contar desde la a.

Aqui va una versión mas eficiente

Código
  1. #include <stdio.h>
  2. #include <ctype.h>
  3.  
  4. int main()
  5. {
  6.     int i, j, des, a, z;
  7.     char cadena[30] = "";
  8.  
  9.     printf("Ingrese una cadena: ");
  10.     scanf("%s", cadena);
  11.  
  12.     printf("Ingrese desplazamiento: ");
  13.     scanf(" %d", &des);
  14.  
  15.     for(i = 0; cadena[i]!='\0'; i++)
  16.     {
  17.        a = 97;
  18.        if(isupper(cadena[i])) a = 65;
  19.        cadena[i] =((cadena[i]-a+des)%26)+a;
  20.      }
  21.      printf("\nCifrado es: %s \n", cadena);
  22.  
  23.     for(j = 0; cadena[j]!='\0'; j++)
  24.     {
  25.        z = 122;
  26.        if(isupper(cadena[j])) z = 90;
  27.        cadena[j]= ((cadena[j]-z-des)%26)+z;
  28.      }
  29.  
  30.      printf("\nDecifrado es: %s \n", cadena);
  31.  
  32.     return 0;
  33. }
  34.  

Saludos  ::)


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 12 Junio 2013, 19:49 pm
Son unos programadores grosos!

Sucedía lo mismo de siempre, no mostraba el resultado si no que se cerraba le agregue esto y listo...

     getchar();
 
 getchar();
 }

:D eliminando el return 0;

Saludos.


Título: Re: Como cifrar letra por letra en C++
Publicado por: amchacon en 12 Junio 2013, 20:15 pm
Son unos programadores grosos!

Sucedía lo mismo de siempre, no mostraba el resultado si no que se cerraba le agregue esto y listo...

     getchar();
 
 getchar();
 }

:D eliminando el return 0;

Saludos.
No elimines el return 0, vas en contra del estándar.


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 12 Junio 2013, 20:51 pm
No elimines el return 0, vas en contra del estándar.

Pero si no ha pasado nada el programa corre normalmente!!!?

Intente con el

   getchar();

      return 0;

  getchar();

y no me funciono así que borre el return 0;
 ;D ?


Título: Re: Como cifrar letra por letra en C++
Publicado por: amchacon en 12 Junio 2013, 21:09 pm
Código
  1. return 0;


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 12 Junio 2013, 21:21 pm
Código
  1. return 0;

Lo intentare de esa manera..


Título: Re: Como cifrar letra por letra en C++
Publicado por: leosansan en 12 Junio 2013, 22:01 pm
Código
  1. return 0;

El return es OBLIGADO en el estandar C , toda vez que de acuerdo  dicho estandar la función¡ón main ha de ser declarada con de tipo int y esto conconllleba a un return de un valor int,. Cositas del estandar. Otra cosa es que sin él te funcione ya que algunos compiladores son muy listos y "corrigen" ciertos aspectos del código.

Así que sigue las indicaciones de amchacon.

Saluditos!.
     (http://st.forocoches.com/foro/images/smilies/aaaaa.gif)






Título: Re: Como cifrar letra por letra en C++
Publicado por: leosansan en 12 Junio 2013, 22:09 pm
Y que sucede si en mi cadena tengo algun caracter estilo " @#$*{}", la tabla ascii no es solo el abecedario.

Estamos hablando del cifrado César y hay que colocar las cosas en su contexto histórico y de acuerdo a ello proceder,. ¿O es que en la época de Julio César existían los símbolos que mencionas'. Ni existía Internet, y por tanto @ ni los móviles con sus almohadillas # ni el dólar $, etc.

Así que para hacer códigos comparables, siñemosnos al estricto cifrado César.


Saluditos!.
     (http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Como cifrar letra por letra en C++
Publicado por: leosansan en 12 Junio 2013, 22:22 pm
Aqui va una versión mas eficiente


Lamentablemente se queda "corto ya que no permite introducir frases. Una pequeña mejora, pero reconozco que está ingenioso.


Saluditos!.
     (http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 12 Junio 2013, 22:31 pm
El return es OBLIGADO en el estandar C , toda vez que de acuerdo  dicho estandar la función¡ón main ha de ser declarada con de tipo int y esto con nlleba a un return de un valor int,. Cositas del estandar. Otra cosa es que sin él te funcione ya que algun9s compiladores son muy listos y "corrigen" ciertos aspectos del código.

así que sigue las indicaciones de amchacon.

Saluditos!.
     (http://st.forocoches.com/foro/images/smilies/aaaaa.gif)

Ok gracias No sabia eso!  :P







Título: Re: Como cifrar letra por letra en C++
Publicado por: xv0 en 12 Junio 2013, 23:23 pm
El cifrado César lo único que hace para cifrar es sumar 3 a cada carácter y para descifrar restar, por lo que he leido.

Aqui esta el mio pero en ASM.

Código
  1. _C.0:
  2.  
  3. incl %edx
  4. scasb
  5. jne _C.0
  6.  
  7. _C.1:
  8.  
  9. decl %edi
  10. addb $0x3, (%edi)
  11. decl %edx
  12. jne _C.1
  13.  
  14. movl %edi, %eax
  15. ret


Así que para hacer códigos comparables, siñemosnos al estricto cifrado César.

Ese código es el cifrado César, solo para el abecedario lo veo una tonteria.

Un saludo.


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 12 Junio 2013, 23:38 pm
El cifrado César lo único que hace para cifrar es sumar 3 a cada carácter y para descifrar restar, por lo que he leido.

Aqui esta el mio pero en ASM.

Código
  1. _C.0:
  2.  
  3. incl %edx
  4. scasb
  5. jne _C.0
  6.  
  7. _C.1:
  8.  
  9. decl %edi
  10. addb $0x3, (%edi)
  11. decl %edx
  12. jne _C.1
  13.  
  14. movl %edi, %eax
  15. ret

Ese código es el cifrado César, solo para el abecedario lo veo una tonteria.

Un saludo.

Perdón mi ignorancia pero como ejecuto un code en ASM?
(ademas en el titulo dice C/C++)

Saludos.


Título: Re: Como cifrar letra por letra en C++
Publicado por: cypascal en 13 Junio 2013, 00:06 am
Creo que no hace falta compilarlo, con la ventana de comandos de windows probablemente baste.

Edito: Si que hace falta por lo menos un ensamblador.

Salu10


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 13 Junio 2013, 00:24 am
Creo que no hace falta compilarlo, con la ventana de comandos de windows probablemente baste.

Edito: Si que hace falta por lo menos un ensamblador.

Salu10

Y como lo compilo y ejecuto?
 :-X


Título: Re: Como cifrar letra por letra en C++
Publicado por: daryo en 13 Junio 2013, 00:30 am
Y como lo compilo y ejecuto?
 :-X

no te lies con asm aun


Título: Re: Como cifrar letra por letra en C++
Publicado por: xv0 en 13 Junio 2013, 01:13 am
Y como lo compilo y ejecuto?
 :-X

Creo que esto bastará, no programo en windows.

Código
  1. char *cesar (char *ptr)
  2.  
  3. {
  4.  
  5. __asm
  6.  
  7.  {
  8.        xor eax, eax
  9.        xor ecx, ecx
  10.        mov edi, ebx
  11.  
  12. _C.0:
  13.        inc ecx
  14.        scasb
  15.        jne _C.0
  16.  
  17. _C.1:
  18.        dec edi
  19.        add byte ptr [edi], 0x3
  20.        dec ecx
  21.        jne _C.1
  22.        mov eax, edi
  23.  }
  24.  
  25. }

La llamas como si fuera una función de C, y esta te devuelve un puntero, haber si te funciona.

Un saludo.


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 13 Junio 2013, 01:26 am
La verdad es que no se NADA sobre ASM u__u y tienes razón no me meteré aun con ASM  ;D

Saludos.


Título: Re: Como cifrar letra por letra en C++
Publicado por: leosansan en 13 Junio 2013, 16:48 pm
El cifrado César lo único que hace para cifrar es sumar 3 a cada carácter y para descifrar restar, por lo que he leido.

Pues no, no es añadir estrictamente 3 sino un valor que el usuario indique. Vamos que es variable.

Ese código es el cifrado César, solo para el abecedario lo veo una tonteria.


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.

Tu propuesta, por ejemplo, sería clasificada como "rarita", ya que se sale del contexto habitual y,como tal propuesta "rarita" yo la aplaudo. Eso sí, echo en falta que expliques a los neófitos en el tema del ensamblador qué herramientas serían necesarias para poder ejecutar el código que planteas. Ya que haces una propuesta fuera del contexto C/C++ una breve explicación no nos vendría mal a algunos.


Saluditos!
   
(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Como cifrar letra por letra en C++
Publicado por: leosansan en 14 Junio 2013, 11:11 am

Un "collage" con las propuestas de cypascal y CCross reunidas pero con función:

Código
  1. #include <stdio.h>
  2. #include <ctype.h>
  3. void cesar (char *cadena , int letra, int des);
  4. int main()
  5. {
  6.    int  des=0, letra=0;
  7.    char cadena[256]={0};
  8.    puts("Ingrese una cadena: ");
  9.    gets (cadena);
  10.    //fgets (cadena,255,stdin);
  11.    do
  12.    {
  13.        puts("\nIndica el desplazamiento: ");
  14.        scanf ("%d",&n);
  15.        while (getchar()!='\n');
  16.    }while (n<0 || n>25);
  17.    cesar (cadena,97,des);
  18.    printf("\nCifrado es: %s \n", cadena);
  19.    cesar (cadena,122,-des);
  20.    printf("\nDecifrado es: %s \n", cadena);
  21.    return 0;
  22. }
  23. void cesar (char cadena[] , int letra, int des)
  24. {
  25.    int i,letra1=0;
  26.    for(i = 0; cadena[i]; i++)
  27.     {
  28.        if ( cadena[i]==' ')
  29.            continue;
  30.        letra1=letra;
  31.        if(isupper(cadena[i])!=0)
  32.            letra1-=32;
  33.        cadena[i] =((cadena[i]-letra1+des)%26)+letra1;
  34.      }
  35. }
  36.  

Saluditos!
   
(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)

P.D:

Creo que esto bastará, no programo en windows.

Código
  1. char *cesar (char *ptr)
  2.  
  3. {
  4.  
  5. __asm
  6. ..............
  7. }
  8.  

¿Una función char que no retorna nada?.


Título: Re: Como cifrar letra por letra en C++
Publicado por: xv0 en 14 Junio 2013, 12:22 pm
P.D:

¿Una función char que no retorna nada?.

Código
  1. ret


Título: Re: Como cifrar letra por letra en C++
Publicado por: leosansan en 16 Junio 2013, 19:37 pm
Código
  1. ret

¿ret?, en C/C++ lo que yo conozco es return. Y aún así no funciona. ¿Podrías indicarnos que programa usas para programar en ensamblador?.

Y puestos a buscar soluciones "curiosas" me dio por encontrar una solución en que sólo se sume y reste el desplazamiento y sin más librería que stdio. Eso sí, he tenido que usar un "señor" array, pero conseguí el propósito mencionado:


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[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"};
  7.    while(1)
  8.    {
  9.        printf("Ingrese una cadena: ");
  10.        fgets (frase,255,stdin);
  11.        do
  12.        {
  13.            puts("Ingrese desplazamiento: (1-25) ");
  14.            scanf ("%d",&desplazamiento);
  15.            while (getchar()!='\n');
  16.        }while (desplazamiento<0 || desplazamiento>25);
  17.        for(i = 0; frase[i]; i++)
  18.        {
  19.            for(j = 0; j<26; j++)
  20.            {
  21.  
  22.                if ( frase[i]==' ')
  23.                    break;
  24.                if (frase[i]==abc[j])
  25.                {
  26.                    frase[i] =  abc[j+ desplazamiento];
  27.                    break;
  28.                }
  29.            }
  30.            for(j = 78; j<104; j++)
  31.            {
  32.  
  33.                if ( frase[i]==' ')
  34.                    break;
  35.                if (frase[i]==abc[j])
  36.                {
  37.                    frase[i] =  abc[j+ desplazamiento];
  38.                    break;
  39.                }
  40.            }
  41.        }
  42.        printf("Cadena cifrada: %s\n\n", frase);
  43.        for(i = 0; frase[i]; i++)
  44.          {
  45.            for(j = 52;j<78 ; j++)
  46.            {
  47.                if ( frase[i]==' ')
  48.                    break;
  49.                if (frase[i]==abc[j])
  50.                {
  51.                    frase[i] =  abc[j- desplazamiento];
  52.                    break;
  53.                }
  54.            }
  55.            for(j = 130;j<156 ; j++)
  56.            {
  57.                if ( frase[i]==' ')
  58.                    break;
  59.                if (frase[i]==abc[j])
  60.                {
  61.                    frase[i] =  abc[j- desplazamiento];
  62.                    break;
  63.                }
  64.            }
  65.        }
  66.        printf("Cadena descifrada: %s\n", frase);
  67.    }
  68.    return 0;
  69. }
  70.  

Saluditos!
(http://i1280.photobucket.com/albums/a497/leosansan/leosan1/leones%20peques/leonpersonajepeque_zps25f3622f.jpg)


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 en 16 Junio 2013, 21:03 pm
El código es similar al anterior


Título: Re: Como cifrar letra por letra en C++
Publicado por: xv0 en 17 Junio 2013, 08:47 am
¿ret?, en C/C++ lo que yo conozco es return. Y aún así no funciona. ¿Podrías indicarnos que programa usas para programar en ensamblador?.

GAS, ld y cualquier editor de texto.

Y puestos a buscar soluciones "curiosas" me dio por encontrar una solución en que sólo se sume y reste el desplazamiento y sin más librería que stdio. Eso sí, he tenido que usar un "señor" array, pero conseguí el propósito mencionado

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

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.

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

Venga hombre.

Un saludo.

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.


Título: Re: Como cifrar letra por letra en C++
Publicado por: amchacon 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:


Título: Re: Como cifrar letra por letra en C++
Publicado por: leosansan 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!
(http://i1280.photobucket.com/albums/a497/leosansan/leosan1/leones%20peques/lion14peque_zps1d213b80.jpg)


Título: Re: Como cifrar letra por letra en C++
Publicado por: Royca3 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)


Título: Re: Como cifrar letra por letra en C++
Publicado por: leosansan 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:


(http://i1280.photobucket.com/albums/a497/leosansan/GRAFICOS1/descifrado_zps9055047e.jpg)

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 (http://es.wikipedia.org/wiki/Cifrado_C%C3%A9sar).

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:


(http://i1280.photobucket.com/albums/a497/leosansan/GRAFICOS1/cifrado1_zps131723c9.jpg)

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!
    
(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Como cifrar letra por letra en C++
Publicado por: amchacon 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).


Título: Re: Como cifrar letra por letra en C++
Publicado por: leosansan 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!
(http://i1280.photobucket.com/albums/a497/leosansan/leosan1/leones%20peques/leonpersonajepeque_zps25f3622f.jpg)


Título: Re: Como cifrar letra por letra en C++
Publicado por: do-while 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?


Título: Re: Como cifrar letra por letra en C++
Publicado por: erest0r 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