Anteriormente vimos cómo implementar el algoritmo de cifrado de César en Python, ahora veremos cómo cifrar y descifrar una oración usando el cifrado César igualmente, pero en el lenguaje de programación C.

Implementar el algoritmo en C es un poco más complicado que en otros lenguajes, sobre todo por la manipulación de cadenas, pero eso no es un impedimento.

Cifrado César en C

Veamos entonces cómo codificar el algoritmo de cifrado César en C.

Explicación general del algoritmo

Ya vimos cómo funciona el cifrado en términos generales. Ahora explicaré cómo usamos las funciones que provee C para alcanzar los resultados esperados, y cómo va el algoritmo general.

Recorremos la cadena letra por letra. A esa letra la convertimos a su representación entera, le sumamos las rotaciones necesarias y luego la convertimos de nuevo en letra; todo esto usando índices de cadenas y el código ASCII. Para decodificar o descifrar simplemente restamos en lugar de sumar.

Para saber si el carácter es una letra, usamos la función isalpha; porque lo que no sea una letra no lo vamos a procesar. De igual manera, para saber si una letra es mayúscula usamos isupper, lo necesitamos para saber cuál alfabeto usar.

Por otro lado, definimos algunas constantes como el máximo que puede tener la cadena, el código ascii de la a y de la A, la longitud del alfabeto y una función que calcula el módulo de un número y lo regresa de manera positiva.

Como necesitamos a ord, usamos la función equivalente que vimos anteriormente. Otra cosa importante es la iteración de la cadena; usamos un simple while aumentando un contador.

Hablando del ciclo while, si el carácter no es una letra, utilizamos la palabra reservada continue; la cual sirve para saltar a la siguiente iteración y no ejecutar el código que sigue.

Antes de ver el algoritmo: aclaración sobre la lectura de la cadena

El algoritmo como tal, funciona perfectamente. Tal vez sea complicada la parte en donde escaneamos la cadena, pero es porque fgets es mejor que scanf en cuanto a seguridad.

De todas maneras, la función trabaja por sí sola, la manera en la que le mandemos la cadena es cosa nuestra; en mi caso lo pongo de manera interactiva para que el usuario pueda probar fácilmente.

Codificación del algoritmo

Aquí está todo el código, incluye las funciones necesarias para codificar una cadena en C utilizando el método César.

/*
        Mi implementación del cifrado César en C
        @author parzibyte
*/#include <stdio.h>  // printf
#include <ctype.h>  // isalpha, isupper
#include <string.h> // strcspn
#define LONGITUD_ALFABETO 26
#define INICIO_ALFABETO_MAYUSCULAS 65
#define INICIO_ALFABETO_MINUSCULAS 97
// Puedes ampliarlo si gustas, recuerda poner uno más aparte de la cantidad que
// escaneas
#define MAXIMA_LONGITUD_CADENA 5000
#define MOD(i, n) (i % n + n) % n // Calcular módulo positivo, gracias a
// https://stackoverflow.com/a/14997413/5032550

const char *alfabetoMinusculas = "abcdefghijklmnopqrstuvwxyz",
           *alfabetoMayusculas = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// Recibe un mensaje a cifrar y un búfer en donde pondrá el resultado, así como
// las rotaciones que debe dar
void cifrar(char *mensaje, char *destino, int rotaciones);

// Recibe un mensaje a descifrar y un búfer en donde pondrá el resultado, así
// como las rotaciones que debe dar
void descifrar(char *mensaje, char *destino, int rotaciones);

// Obtener el valor entero de un carácter:
// https://parzibyte.me/blog/2018/12/11/ord-chr-c/
int ord(char c);

int main(void) {
  // El original, el cifrado y luego el descifrado
  char mensaje[MAXIMA_LONGITUD_CADENA], mensajeCifrado[MAXIMA_LONGITUD_CADENA],
      mensajeDescifrado[MAXIMA_LONGITUD_CADENA];
  printf("Escribe un mensaje para que lo cifre [Máximo %d caracteres]:\n",
         MAXIMA_LONGITUD_CADENA - 1);
  // Esto es para obtener el mensaje y evitar desbordamientos; se puede ignorar
  fgets(mensaje, MAXIMA_LONGITUD_CADENA, stdin);
  /*Quitar el salto de línea*/ mensaje[strcspn(mensaje, "\r\n")] = 0;
  // ¿Cuántas rotaciones?
  int rotaciones;
  printf("Escribe el número de rotaciones que se darán a las letras:\n");
  scanf("%d", &rotaciones);
  // Ahora sí ciframos y descriframos
  printf("El mensaje original es: %s\n", mensaje);
  cifrar(mensaje, mensajeCifrado, rotaciones);
  printf("El mensaje cifrado es: %s\n", mensajeCifrado);
  descifrar(mensajeCifrado, mensajeDescifrado, rotaciones);
  printf("El mensaje descifrado es: %s\n", mensajeDescifrado);
  return 0;
}

void cifrar(char *mensaje, char *destino, int rotaciones) {
  /*Recorrer cadena*/  int i = 0;
  while (mensaje[i]) {
    char caracterActual = mensaje[i];
    int posicionOriginal = ord(caracterActual);
    if (!isalpha(caracterActual)) {
      destino[i] = caracterActual;
      i++;
      continue; // Ir a la siguiente iteración; por eso arriba aumentamos a i
    }
    if (isupper(caracterActual)) {
      destino[i] =
          alfabetoMayusculas[(posicionOriginal - INICIO_ALFABETO_MAYUSCULAS +
                              rotaciones) %
                             LONGITUD_ALFABETO];
    } else {

      destino[i] =
          alfabetoMinusculas[(posicionOriginal - INICIO_ALFABETO_MINUSCULAS +
                              rotaciones) %
                             LONGITUD_ALFABETO];
    }
    i++;
  }
}

void descifrar(char *mensaje, char *destino, int rotaciones) {
  /*Recorrer cadena*/  int i = 0;
  while (mensaje[i]) {
    char caracterActual = mensaje[i];
    int posicionOriginal = ord(caracterActual);
    if (!isalpha(caracterActual)) {
      destino[i] = caracterActual;
      i++;
      continue; // Ir a la siguiente iteración; por eso arriba aumentamos a i
    }
    if (isupper(caracterActual)) {
      destino[i] = alfabetoMayusculas[MOD(
          posicionOriginal - INICIO_ALFABETO_MAYUSCULAS - rotaciones,
          LONGITUD_ALFABETO)];
    } else {
      destino[i] = alfabetoMinusculas[MOD(
          posicionOriginal - INICIO_ALFABETO_MINUSCULAS - rotaciones,
          LONGITUD_ALFABETO)];
    }
    i++;
  }
}
int ord(char c) { return (int)c; }

En el método main puse un ejemplo de uso. Espero que sea claro.

Uso de las funciones

Si quieres cifrar, reserva 2 búfers o cadenas del mismo tamaño: una que tiene el mensaje original y otra en donde será puesto el mensaje cifrado.

En caso de que quieras descifrar, igualmente reserva 2 búfers del mismo tamaño. En uno pon el mensaje cifrado, y en el otro se pondrá el mensaje descifrado.

Todo esto, sin importar si cifras o no, está determinado por el número de rotaciones. Recuerda que si, por ejemplo, cifras con 3 rotaciones, debes hacer la operación inversa con el mismo número.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Ver comentarios

Entradas recientes

Creador de credenciales web – Aplicación gratuita

Hoy te voy a presentar un creador de credenciales que acabo de programar y que…

1 semana hace

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

2 semanas hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

2 semanas hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

2 semanas hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

2 semanas hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

2 semanas hace

Esta web usa cookies.