Quiero mostraros un sencillo código en C que simula un cifrado por el método Cesar. Este es un sistema criptográfico por sustitución, es decir, se sustituye cada letra por otra del alfabeto que está desplazado un número fijo. Es uno de los métodos más sencillos y antiguos que existen.

Su nombre se debe al gobernante romano Cesar, quien lo utilizó para cifrar sus mensajes. Ha sido empleado hasta bien entrado el siglo XX por algunos ejércitos.

En nuestro programa establecemos dos abecedarios, uno en mayúsculas y otro en minúsculas. La mecánica es bien sencilla, el procedimiento de cifrado y descifrado recorre el mensaje plano / mensaje cifrado letra a letra sustituyéndola por otra que se encuentra a una distancia determinada.

Veamos el fichero que contiene la funciones y procedimientos de cabecera.

#ifndef CIFRADOCESAR_H_
#define CIFRADOCESAR_H_

#define LONGITUDALFABETO 26
#define INICIOALFABETOMAYUSCULAS 65
#define INICIOALFABETOMINUSCULAS 97

#define LONGITUDMAXIMACADENA 5000

#define MOD(i, n) (i % n + n) % n

void cifrar ( char* mensaje, char* textocifrado, int rotaciones );
void descifrar ( char* textocifrado, char* textodescifrado, int rotaciones );

int ord ( char c );



#endif

A continuación, os muestro el desarrollo de cada uno de los procedimientos para cifrar o descifrar un mensaje que tendrá como longitud mensaje máxima 5000 letras.

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

#include "cifradocesar.h"

const char *alfabetoMinusculas = "abcdefghijklmnopqrstuvwxyz";
const char *alfabetoMayusculas = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

int ord ( char c ) { return (int) c; }

void cifrar ( char* mensaje, char* textocifrado, int rotaciones ) {

	int contador = 0;

	while ( mensaje[contador] ) {
		char caracteractual = mensaje[contador];
		int posicionoriginal = ord ( mensaje[contador] );

		if (!isalpha(caracteractual)) {
			textocifrado[contador] = caracteractual;
			contador++;
			continue;
		}

		if (isupper(caracteractual)) {
			textocifrado[contador] = alfabetoMayusculas[MOD(posicionoriginal - INICIOALFABETOMAYUSCULAS +
			                              rotaciones,
										  LONGITUDALFABETO)];
		} else {
			textocifrado[contador] = alfabetoMinusculas[MOD(posicionoriginal - INICIOALFABETOMINUSCULAS +
						                              rotaciones,
						                             LONGITUDALFABETO)];
		}

		contador++;

	}

}

void descifrar ( char* textocifrado, char* textodescifrado, int rotaciones )  {

	int contador = 0;

	while ( textocifrado[contador] ) {
		char caracteractual = textocifrado[contador];
		int posicionoriginal = ord ( textocifrado[contador] );

		if (!isalpha(caracteractual)) {
			textodescifrado[contador] = caracteractual;
			contador++;
			continue;
		}

		if (isupper(caracteractual)) {
			textodescifrado[contador] = alfabetoMayusculas[MOD(
			          posicionoriginal - INICIOALFABETOMAYUSCULAS - rotaciones,
			          LONGITUDALFABETO)];
		} else {
			textodescifrado[contador] = alfabetoMinusculas[MOD (posicionoriginal - INICIOALFABETOMINUSCULAS -
													  rotaciones,
													 LONGITUDALFABETO)];
		}

		contador++;

	}

}

Por último os dejo un pequeño programa de prueba con el que podréis comprobar que efectivamente funciona.

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

#include "cifradocesar.h"


int main(void) {

  char mensaje[LONGITUDMAXIMACADENA], mensajeCifrado[LONGITUDMAXIMACADENA],
      mensajeDescifrado[LONGITUDMAXIMACADENA];

  printf("Escribe un mensaje para que lo cifre [Máximo %d caracteres]:\n",
		  LONGITUDMAXIMACADENA - 1);

  fgets(mensaje, LONGITUDMAXIMACADENA, stdin);
  mensaje[strcspn(mensaje, "\r\n")] = 0;

  int rotaciones;
  printf("Escribe el número de rotaciones que se darán a las letras:\n");
  scanf("%d", &rotaciones);

  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;
}

Como siempre, estoy a vuestra disposición para resolveros cualquier duda a través de mi sección de comentario.

Dejar respuesta

Please enter your comment!
Please enter your name here