Cifrado cesar con C

Iniciado por Zackonit, Mayo 10, 2022, 02:32:56 AM

Tema anterior - Siguiente tema

0 Miembros y 3 Visitantes están viendo este tema.

Mayo 10, 2022, 02:32:56 AM Ultima modificación: Abril 27, 2023, 07:21:40 PM por DtxdF Razón: Mal formateado.
Buenas tardes sean a todos , pues he estado viendo muchos cifrados en internet pero ninguno me convence o de plano para lo que recien se inician en el lenguaje C es complicado de leer ,asi que les traigo el cifrado cesar usando arrays
y punteros ,pueden mejorar el codigo y ponerlo abajo el objetivo de esto es aprender tecnicas

Bueno mucho blablabla ,aqui el code

Código: c
#include <stdio.h>

void caesarCipher(int key, char *keyword,int size);

int main(int argc,char const *argv[]){
        char msg[4] = "hola";
        char *keyword = &msg;
        caesarCipher(3,keyword,4);
        return 0;
}

void caesarCipher(int key ,char *keyword,int size){
        char abc[26] = {'a','b','c','d','e',
                        'f','g','h','i','j',
                        'k','l','m','n','o',
                        'p','q','r','s','t',
                        'u','v','w','x','y',
                        'z'};
    int buffersize = sizeof(abc)/sizeof(abc[0]);
    int z=0;

    for(int i=0;i<size;i++){
        for(int j=0;j<buffersize;j++){
            if(keyword[i] == abc[j]){
              z = j+key;
                  printf("%c",abc[z]);          
              if(z > buffersize){
                  printf("%c",abc[z-buffersize]);

              } 
            } 
        }
    }
}



puedes no tener que utilizar una liista de letras haciendo un cast a int y despues casteando de nuevo a char.

Algo asi:

Código: php

cifrado[i]=(char)(69+((((int)limpio[i]))-69)+key);

Lo siento, no contesto dudas por MP, si tienes dudas las planteas en el foro.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
puedes no tener que utilizar una liista de letras haciendo un cast a int y despues casteando de nuevo a char.

Algo asi:

Código: php

cifrado[i]=(char)(69+((((int)limpio[i]))-69)+key);


Podrias subir el code de tu solucion para poder examinarla con detenimiento?

Abril 27, 2023, 07:15:17 PM #3 Ultima modificación: Abril 27, 2023, 07:26:20 PM por DtxdF
No tienes permitido ver los links. Registrarse o Entrar a mi cuentaBuenas tardes sean a todos , pues he estado viendo muchos cifrados en internet pero ninguno me convence o de plano para lo que recien se inician en el lenguaje C es complicado de leer ,asi que les traigo el cifrado cesar usando arrays
y punteros ,pueden mejorar el codigo y ponerlo abajo el objetivo de esto es aprender tecnicas

Bueno mucho blablabla ,aqui el code

Código: c
#include <stdio.h>

void caesarCipher(int key, char *keyword,int size);

int main(int argc,char const *argv[]){
        char msg[4] = "hola";
        char *keyword = &msg;
        caesarCipher(3,keyword,4);
        return 0;
}

void caesarCipher(int key ,char *keyword,int size){
        char abc[26] = {'a','b','c','d','e',
                        'f','g','h','i','j',
                        'k','l','m','n','o',
                        'p','q','r','s','t',
                        'u','v','w','x','y',
                        'z'};
    int buffersize = sizeof(abc)/sizeof(abc[0]);
    int z=0;

    for(int i=0;i<size;i++){
        for(int j=0;j<buffersize;j++){
            if(keyword[i] == abc[j]){
              z = j+key;
                  printf("%c",abc[z]);          
              if(z > buffersize){
                  printf("%c",abc[z-buffersize]);

              } 
            } 
        }
    }
}


En lugar de:
Código: php
        char abc[26] = {'a','b','c','d','e',
                        'f','g','h','i','j',
                        'k','l','m','n','o',
                        'p','q','r','s','t',
                        'u','v','w','x','y',
                        'z'};

haz mejor:
Código: c
        char abc[] = "abcdefghijklmnopqrstuvwyz";

En lugar de hacer esto, que es innecesario:
Código: c
char *keyword = &msg;
pasale msg a la funcion directamente, es correcto:
Código: c
caesarCipher(3,msg,4);

En lugar de poner 4, es mejor usar sizeof(msg) para evitar problemas, aunque en este caso no afecta.
Código: php
caesarCipher(3,msg,sizeof(msg));

aunque esto es innecesario, el tener que pasar el tamaño por función, además que solo te sirve si ya conoces el tamaño del string o si esta declaro en el stack y puedes averiguar su tamaño usando sizeof(). El resto de las veces, se usara strlen(), función de la cabecera string.h que te permite obtener el tamaño de un string.
Luego otras cosa que podemos hacer es agregarle un cuarto argumento en la función que sea un array donde se vaya depositando el contenido ya cifrado, por si queremos usarlo a lo largo del programa para guardarlo en un archivo o similar.
Otro detalle a tener en cuenta es ese doble for que te esta costando una cantidad de i * j iteraciones, lo que es algo caro en términos de tiempo.

Aqui te reporto mi solución, me he tomado la molestia de agregar una función que desencripte:
Código: c
#include <stdio.h>
#include <string.h>

#define ASCII_VALUE_a 97
#define ASCII_VALUE_z 122

#define ASCII_VALUE_A 65
#define ASCII_VALUE_Z 90

void caesarCipher(unsigned char key, const char *msg, char *msg_cifrados);
void desCaesarCipher(unsigned char key, const char *msg, char *msg_descifrados);

int main(int argc, char const *argv[])
{
    char msg[] = "hHoIlLaA";
    char msg_cifrados[sizeof(msg)];

    caesarCipher(2, msg, msg_cifrados);
    printf("\ndatos cifrados almacenados en msg_cifrados: %s", msg_cifrados);

    char msg_descifrados[sizeof(msg)];

    desCaesarCipher(2, msg_cifrados, msg_descifrados);
    printf("\ndatos descifrados en msg_descifrados: %s", msg_descifrados);

    return 0;
}

void caesarCipher(unsigned char key, const char *msg, char *msg_cifrados)
{

    for (unsigned long int i = 0; i < strlen(msg); i++){

        if (msg[i] >= ASCII_VALUE_a && msg[i] <= ASCII_VALUE_z) {
            // la letra es minuscula
            msg_cifrados[i] = msg[i] + key % (ASCII_VALUE_z - ASCII_VALUE_a) ;
        } else if (msg[i] >= ASCII_VALUE_A && msg[i] <= ASCII_VALUE_Z){
            // la letra es mayuscula
            msg_cifrados[i] = msg[i] + key % (ASCII_VALUE_Z - ASCII_VALUE_A);
        }

    }

}
void desCaesarCipher(unsigned char key, const char *msg, char *msg_descifrados)
{

    for (unsigned long int i = 0; i < strlen(msg); i++){

        if (msg[i] >= ASCII_VALUE_a && msg[i] <= ASCII_VALUE_z) {
            // la letra es minuscula
            msg_descifrados[i] = msg[i] - key % (ASCII_VALUE_z - ASCII_VALUE_a) ;
        } else if (msg[i] >= ASCII_VALUE_A && msg[i] <= ASCII_VALUE_Z){
            // la letra es mayuscula
            msg_descifrados[i] = msg[i] - key % (ASCII_VALUE_Z - ASCII_VALUE_A);
        }

    }

}


Para quitarnos bucles extras de encima, aprovechamos que sepamos el valor ascii de los caracters 'a'(97) y 'z'(122), con esto podemos saber si realizamos la resta que 122-97 = 25letras minúsculas.
También sabemos que el rango para las letras mayúsculas abarca de 65('A') a 90('Z').
Lo que haremos sera recorrer los datos cifrados o sin descifrar, depende de cual de las dos funciones hablemos y realizaremos estas restas anteriormente explicadas, tras identificar si la "i" letra de msg es mayúscula o minúscula. Asi podemos determinar si usar el rango de letras mayúsculas o minúsculas. Una vez hecho esto, hacemos la operación modulo a key, con esto nos aseguramos de que, sea el valor que sea key, siempre se encuentre entre un valor que podamos usar para hacer el desplazamiento de diccionario. Una vez tenemos una clave que sepamos que esta entre los limites del rango minúscula o mayúscula, se lo sumamos(encriptar) a la "i" letra de msg o se lo restamos(desencriptar). también mencionar que hemos usado const char por que msg no va a ser un valor a modificar a lo largo de la función. hemos puesto que la key sea sin signo, por que si queremos un desplazamiento negativo, solo habra que exceder el doble del valor limite del rango de valores ASCII de las letras mayúsculas o minúsculas. también agregue que los cambios se guarden en otras variables del mismo tamaño que msg, ya que el tamaño de los datos cifrados y sin descifrar es el mismo también.