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; }
d555
Great!!
Obs: el primer código está comentado la myor parte de los métodos.
Jamiel
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++
David
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
camilo
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
Adrian
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