Cifrados: César

Iniciando una serie de artículos sobre cifrados criptográficos vamos a empezar con uno muy famoso, César o Caesar, un cifrado que se usaba en la antigua roma (su nombre es en honor a Julio César) para cifrar los mensajes, es por sustitución simple y su funcionamiento es el siguiente:

Se ingresa un texto cualquiera y una semilla que en este caso será un número, ese número correrá la posición de la letra en cuestión n veces en el alfabeto común, ósea si se ingresa el texto «A» y la semilla 28 entonces se procede a hacer la suma, la letra A tiene la posición 0, viéndolo desde una maquina se toma cero como la primera posición; se suman 0 y la semilla en este caso 28 y el resultado como tiene que estar dentro del alfabeto entonces se modula o se divide el resultado de la suma sobre la longitud del alfabeto y se toma el residuo como indexo de la nueva letra en su estado cifrado, ósea:

28%26 = 2
Caesar("A")="C"

Del concepto al código

Conociendo el funcionamiento del cifrado, el paso a seguir es convertir el concepto a código y así automatizar el proceso de cifrado/descifrado. A continuación se muestra el cifrado escrito en varios lenguajes de programación con su respectiva documentación.

César en Java

/*
Modulo Caesar para RiCrypt

Cifrado por sustitución usando sumas y restas modulares en el alfabeto
normal.

Phicar
project-ric.org
[email protected]
*/
// package RiCrypt;
public class Caesar{
public static String CharsetMin = "abcdefghijklmnopqrstuvwxyz";
public static String CharsetMay = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static String TxT;
public static int Pos;
/*
Constructor
@params Txt as String sera el txt a cifrar o a descifrar.
Pos as Integer sera el numero de posiciones a cifrar.
*/
public Caesar(String TxT,int Pos){
this.TxT=TxT;
this.Pos=Pos;
}
/*
Funcion Cifrar
Cifra la cadena de texto introducida en el constructor
bajo el algoritmo Caesar usando una sumatoria modular
de la siguiente manera
(x+y)%p
donde x sera el indexo en el alfabeto de la letra en
cuestion, y sera la posicion o semilla introducida
en el algoritmo y p sera la longitud del alfabeto.
*/
public static String Cifrar(){
String Cifrado = "";
for(int n = 0;n<TxT.length();n++){
if((CharsetMin.indexOf(TxT.charAt(n))!=-1)||(CharsetMay.indexOf(TxT.charAt(n))!=-1))
Cifrado+=(CharsetMin.indexOf(TxT.charAt(n))!=-1)?CharsetMin.charAt(((CharsetMin.indexOf(TxT.charAt(n)))+Pos)%CharsetMin.length()):CharsetMay.charAt((CharsetMay.indexOf(TxT.charAt(n))+Pos)%CharsetMay.length());
else
Cifrado+=TxT.charAt(n);
}
return Cifrado;
}
/*
Funcion DesCifrar
DesCifra el texto cifrado introducido en el constructor
bajo el algoritmo Caesar usando una resta modular
de la siguiente manera
(x-y)%p
donde x sera el indexo en el alfabeto de la letra en
cuestion, y sera la posicion o semilla introducida
en el algoritmo y p sera la longitud del alfabeto.
*/

public static String DesCifrar(){
String DesCifrado = "";
for(int n = 0;n<TxT.length();n++){
if((CharsetMin.indexOf(TxT.charAt(n))!=-1)||(CharsetMay.indexOf(TxT.charAt(n))!=-1))
DesCifrado+=(CharsetMin.indexOf(TxT.charAt(n))!=-1)?CharsetMin.charAt((CharsetMin.indexOf(TxT.charAt(n))-Pos)%CharsetMin.length()):CharsetMay.charAt((CharsetMay.indexOf(TxT.charAt(n))-Pos)%CharsetMay.length());
else
DesCifrado+=TxT.charAt(n);
}
return DesCifrado;
}
}

César en PHP

<?php
/*****************************************************************************
* Nombre : Caesar.php
* Implementación del cifrado de cesar para Project-RIC. Este cifrado usa una clave de
* sustitución simple. En la actualidad existen muchos codes similares a este y el mas
* conocido se llama Rot13, el cual realiza una rotacion de 13 caracteres la cadena original.
* @copyLeft  : Project-RIC
* @package   : RiCrypt
* @author      : D-m-K, [email protected], my.opera.com/d-m-k
/******************************************************************************/
class Caesar {
var $charset;
var $txt;
var $rot;

/*****************************************************************************
* Constructor
* Cifra la cadena pasada como parametro realizando la sustitucion
* de la cadena original la cantidad de veces definida en el parametro
* @param  $s = Cadena original
*                $n = Cantidad de rotaciones a cada letra
******************************************************************************/
public function __construct($s, $n) {
$this->charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";  //Definicion del charset
$this->txt    = $s;
$this->rot    = $n;
}

/*****************************************************************************
* Funcion : encode
* Cifra la cadena pasada como parametro realizando la sustitucion
* de la cadena original la cantidad de veces definida en el parametro
* @return $result = Mensaje cifrado
*****************************************************************************/
function encode(){
$result = "";                                                           //Variable donde queda el resultado
for($i=0; $i<strlen($this->txt); $i++)          //Realizo la sustitución de cada caracter
$result .= $this->rotate($this->txt{$i}, $this->rot);       //Invoco funcion que hace la rotacion
return $result;                                                         //Devuelvo la cadena Cifrada =)
}

/*****************************************************************************
* Funcion : decode
* Cifra la cadena pasada como parametro realizando la sustitucion
* de la cadena original la cantidad de veces definida en el parametro
* @return $result = Mensaje Descifrado
*****************************************************************************/
function decode(){
$result = "";                                                           //Variable donde queda el resultado
for($i=0; $i<strlen($this->txt); $i++)          //Realizo la sustitución de cada caracter
$result .= $this->rotate($this->txt{$i}, -$this->rot);      //Invoco funcion que hace la rotacion
return $result;                                                         //Devuelvo la cadena DesCifrada =)
}

/*****************************************************************************
* Funcion : rotate
* Realiza la rotacion de un caracter sobre el charset dependiendo el valor de la semilla
* de la cadena original la cantidad de veces definida en el parametro
* @param  $s = Cadena original
*                 $n = Cantidad de rotaciones
* @return  $result = Valor del nuevo caracter de acuerdo al indice
*****************************************************************************/
function rotate($c, $n){
$result = "";                                   //Texto de salida
$tamC = strlen($this->charset); //Longitud de la cadena del charset
$k = 0;                                                 //Indice para sustitucion de la cadena con el charset
$n %= $tamC;                                    //Semilla ó rotacion
$c = strtoupper($c);                    //Convierto a mayuscula el caracter
//Evaluo si el caracter en la posicion $i existe, de lo contrario dejo el caracter que esta por defecto
if(strstr($this->charset, $c)){
$k = (strpos($this->charset, $c) + $n);
if($k < 0){                                     //Evaluo que el indice sea mayor a 0
$k += $tamC;
}else
$k %= $tamC;
$result .= $this->charset{$k};  //Obtengo del charset el indice de $k, que es el nuevo valor
}else{
$result .= $c;                          //Dejo el caracter sin modificaciones
}
return $result;                                 //Devuelvo el caracter con el nuevo valor
}
}
?> 
<?php
include 'Caesar.php';                                   //Incluyo la clase
$mensaje   = $_POST['mensaje'];                 //Mensaje a cifrar
$semilla   = $_POST['semilla'];                 //Semilla o cantidad de rotaciones al mensaje
$tarea     = $_POST['tarea'];                   //Boton pulsado por el usuario
$salida    = "";                                                //Variable que guarda el mensaje
//Aqui esta la magia
if($_POST && $mensaje != "" && $semilla != ""){
//CIFRADO DEL MENSAJE
if($_POST['tarea'] == "Cifrar"){
$cipher    = new Caesar($mensaje, $semilla);
$salida = $cipher->encode();
}
//DESCIFRADO DEL MENSAJE
if($_POST['tarea'] == "DesCifrar"){
$cipher    = new Caesar($mensaje, $semilla);
$salida = $cipher->decode();
}
}
?>
<html>
<head>
<title> .:: Implementacion de la cifra de Caesar ::. </title>
</head>
<body>
<h1>Caesar</h1><hr>
<!-- Datos para el cifrado -->
<form method="post">
<strong>Mensaje a cifrar / descifrar :</strong> <br>
<textarea name="mensaje" style="width:500px;border:1px solid #555"><?php echo $_POST['mensaje']; ?></textarea><br>
<strong>Semilla :</strong>
<input type="text" name="semilla" style="width:30px;border:1px solid #555" value="<?php echo $_POST['semilla']; ?>"> |
<input type="submit" name="tarea" value="Cifrar"> |
<input type="submit" name="tarea" value="DesCifrar">
</form>
<?php
//Muestro el mensaje de salida
if($salida != ""){
echo "<strong> Resultado del criptograma </strong> <br> \n";
echo "<div class='mensaje'>" . $salida . "</div>";
}
?>
</body>
</html> 

César en C++

    /************************************************
*  Nombre : Caesar.cpp                          *
*                                               *
*  Cifrado de cesar de sustitución simple       *
*  por medio de sumas y restas del alfabeto     *
*                                               *
*  Fulapol                                      *
*  [email protected]                            *
*  my.opera.com/fulapol                         *
*                                               *
************************************************/

include <string> //Cabecera para el manejo de las cadenas de texto

/************************************************
*                                               *
*  La clase principal se llama Cesar y contiene *
*  los metodos para cifrar y descifrar texto    *
*                                               *
************************************************/

Public Class Cesar{
private:
string letras = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string texto;
int semilla;

//Todas las variables son privadas

public:
cesar(string orig, int pos);
string cifrar();
string descifrar();

//Los metodos son publicos, ya que es la unica
//forma de accesar a las variables

}

/************************************************
*                                               *
*  Constructor de la clase, en el se define el  *
*  texto a cifrar y las posiciones a recorrer   *
*                                               *
************************************************/

cesar::cesar(string orig, int pos){
this->texto.assign(orig);
this->semilla = (pos%letras.length());

//El objeto debe instanciarse con el texto
//original y la posicion que debe de recorrer
//Aqui la semilla se pasa como modulo para
//evitar calculos en el futuro

}

/************************************************
*                                               *
*  El metodo cifrar, que regresa una cadena de  *
*  texto despues de ser cifrada                 *
*                                               *
************************************************/

string cesar::cifrar(){
string final;
int i,movimiento;
size_t pos;
for(i=0;i<texto.length();i++){
if(texto.at(i)>96 && text.at(i)<123)
texto.at(i) -= 32;
//Paso las letras minusculas a mayusculas

if(texto.at(i)<64 && texto.at()i>91)
final.apend(texto.at(i));
//Si el caracter actual no es una letra se
//deja sin cifrar

else{
pos = letras.find(text.at(i));
if(((int)pos+semilla) > letras.legth())
movimiento = ((int)pos+semilla)-letras.length();
else
movimiento = (int)pos+semilla;
//Revision para evitar que el valor quede
//fuera de rango

final.apend(letras,movimiento,1)
}
}
return final;
}

/************************************************
*                                               *
*  El metodo descifrar, que regresa una cadena  *
*  de texto despues de ser descifrada           *
*                                               *
************************************************/

string cesar::descifrar(){
string final;
int i,movimiento;
size_t pos;
for(i=0;i<texto.length();i++){
if(texto.at(i)>96 && text.at(i)<123)
texto.at(i) -= 32;
//Paso las letras minusculas a mayusculas

if(texto.at(i)<64 && texto.at()i>91)
final.apend(texto.at(i));
//Si el caracter actual no es una letra se
//deja sin cifrar

else{
pos = letras.find(text.at(i));
if(((int)pos-semilla) < 0)
movimiento = letras.length()+((int)pos-semilla);
else
movimiento = (int)pos-semilla;
//Revision para evitar que el valor quede
//fuera de rango, como la resta general un
//valor negativo lo sumo al tamaño del
//alfabeto para que avanze hacia atras

final.apend(letras,movimiento,1)
}
}
return final;
}

5 Comentarios

  1. Responder

    Great!!
    Obs: el primer código está comentado la myor parte de los métodos.

  2. Responder

    hola men una pregunta tendras el codiog pero en c y para ver si me lo enseñas es que soy un estudiante de programcion y no se todavia c++

  3. Responder

    Quisiera comentar que el codigo no corre al descifrfar da el siguiente error
    Exception in thread «main» java.lang.StringIndexOutOfBoundsException: String index out of range: -7
    at java.lang.String.charAt(String.java:686)
    at holamundo.Main$Caesar.DesCifrar(Main.java:99)
    at holamundo.Main.main(Main.java:43)
    Java Result: 1

  4. Responder

    Estimados
    Me llegó un texto que es un algoritmo de encriptacion clase 6 con c++ y javaY luego compilado para apk o sea linux
    solicito me puedan ayudar descifrando lo siguiente:

    5cVVnb6zvaxdd7pRPPBn42uo4C7VOPAsUr01VgDiKawvEb/BAXcXohQVOLwdee0iiZc7+q1IZhJO9rC1sI2sDdVLIY1zoL2HKm/Bns7YaT0E31TiDhEXPz8jMbFdPp2Bh6k1flkYllCLPJTsykRGxTPSOPFEc9epJFGKvKLdM8CIhzoUUIb/D+eTokIRPAM8npr6i0t0dUQtWnaUSvbh+Yj1lAVAWZtLZ0I6z+LWsem8Un8TsvhpOsg2qqYLaSh5QQ22Mz6mNb87o5+DRXLyOCD2G+Y2SIgBVeucw4fuJDI6olPrVl23y/vxGsG2PZPM7oPN8bNOjIcV1wasilY7oNsB3AFdTFkFwvQaQvxM8fs8JkpwvsXcV+B3kIJW8xOR

    Gracias

  5. Responder

    El codigo en c++ esta excelente el unico detalle es este if que pusiste asi esta mal
    if(texto.at(i)91)
    final.apend(texto.at(i));

    ya que si revisas la logica un numero o caracter jamas va a ser menor a 64 y mayor a 91 al mismo tiempo lo correcto es poner || en vez de && para que entre cuando se cumple una condicion .
    Y a la hora de usar el append para concatenar un solo char a veces da problemas entonces mejor usar +=

    Saludos

Deja un comentario

Your email address will not be published. Required fields are marked *

You may use these <abbr title="HyperText Markup Language">HTML</abbr> tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>