Cifrados: Vigenère y código en Java, C++ y PHP

Cifrados: Vigenère y código en Java, C++ y PHP

Continuando la serie de artículos sobre cifrados, el turno es para Vigenère un cifrado creado por Leone Battista Alberti que trabaja por sustitución, este algoritmo es muy parecido al Cesar y la diferencia es que tiene una semilla mucho más complicada de hallar ya que esta es una palabra la cual se itera también y se hace la suma de la siguiente manera:

(PosicionTxT + PosicionSeed) % alfabeto.longitud

Del concepto al código

Conociendo el funcionamiento básico de vigenere, pasemos a ver su implementación en diferentes lenguajes de programación:

Códigos disponibles en Github: RiCrypt: Vigenere en Java

Java

/*
Modulo Vigenere para RiCrypt

Cifrado por sustitucion usando sumas y restas modulares en el alfabeto
normal pero altercadas con una semilla como palabra.

Phicar
project-ric.org
[email protected]
*/
public class Vigenere{
public static String TxT,Seed;
public static String Charset = "abcdefghijklmnopqrstuvwxyz";
public Vigenere(String TxT,String Seed){
this.Seed = Desn(Seed);
this.TxT = TxT;
}
public static String Cifrar(){
String Cifrado = "",a=TxT.toLowerCase();
for(int n = 0,c=0;n<TxT.length();n++,c = (c+1)%Seed.length()){
if(Charset.indexOf(a.charAt(n))!=-1){
int tmp = (Charset.indexOf(a.charAt(n))+Charset.indexOf(Seed.charAt(c)))%Charset.length();
Cifrado+=(Charset.indexOf(TxT.charAt(n))!=-1)?Charset.charAt(tmp):String.valueOf(Charset.charAt(tmp)).toUpperCase();
}else{
c-=1;
Cifrado+=TxT.charAt(n);
}
}
return Cifrado;
}
public static String DesCifrar(){
String DesCifrado = "";
String a = TxT.toLowerCase();
for(int n = 0,c=0;n<a.length();n++,c=(c+1)%Seed.length()){
if(Charset.indexOf(a.charAt(n))!=-1){
int tmp = (Charset.indexOf(a.charAt(n))-Charset.indexOf(Seed.charAt(c)));
tmp = (tmp<0)?(tmp+Charset.length()):tmp;
DesCifrado+=(Charset.indexOf(TxT.charAt(n))!=-1)?Charset.charAt(tmp):String.valueOf(Charset.charAt(tmp)).toUpperCase();
}else{
c-=1;
DesCifrado+=TxT.charAt(n);
}
}
return DesCifrado;
}
public static String Desn(String a){
String b = "";
for(int n = 0;n<a.length();n++){
if((Charset.indexOf(a.charAt(n))!=-1)||(Charset.indexOf(String.valueOf(a.charAt(n)).toLowerCase())!=-1))
b+=a.charAt(n);
}
return b;
}
}

C++

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

#include <string>

Public Class Vigenere{
private:
string texto,semilla,letras;
letras = "abcdefghijklmnopqrstuvwxyz"
string limpiar(string cadena);
//Las variables son privadas, el metodo limpiar
//es privada ya que solo lo utilizan los otros
//metodos para limpiar la entrada

public:
vigenere(string orig, string sem);
string cifrar();
string descifrar();
//Esto es publico porque es la unica forma de
//accesar a los datos de la clase

}

/************************************************
*                                               *
*  El Constructor que debe recibir la cadena a  *
*  tratar y la cadena semilla                   *
*                                               *
************************************************/

vigenere::vigenere(string orig, string sem){
this->texto = limpiar(orig);
this->semilla = limpiar(sem);
}

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

vigenere::cifrar(){
string final;
int i,movimiento,rotacion,total;
size_t pos,pos2;
//Las variables serviran para registrar la posicion
//de las letras y calcular la semilla

for(i=0,rotacion=0;i<texto.length();i++,rotacion++){ pos = letras.find(texto.at(i)); pos2 = letras.find(semilla.at(rotacion)); total = ((int)(pos+pos2))%letras.length(); //El total que marca la posicion de la letra y la //semilla sumadas if(total > letras.legth())
movimiento = total-letras.length();
else
movimiento = total;
//Para asegurarnos que esta dentro del rango

final.apend(letras,movimiento,1)
if(rotacion==semilla.length())
rotacion=0;
//Si se acaba la semilla, regresar al principio

}
return final;
}

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

vigenere::descifrar(){
//La funcion es exactamente la misma que en el metodo
//cifrar, solo que aqui las posiciones se restan para
//eliminar la semilla del texto

string final;
int i,movimiento,rotacion,total;
size_t pos,pos2;
for(i=0,rotacion=0;i<texto.length();i++,rotacion++){
pos = letras.find(texto.at(i));
pos2 = letras.find(semilla.at(rotacion));
total = ((int)(pos-pos2))%letras.length();
if(total < 0)
movimiento = total+letras.length();
else
movimiento = total;
final.apend(letras,movimiento,1)
if(rotacion==semilla.length())
rotacion=0;
}
return final;
}

/************************************************
*                                               *
*  El metodo limpiar, que regresa una cadena de *
*  texto que solo contiene los caracteres       *
*  soportados por la clase                      *
*                                               *
************************************************/

vigenere::limpiar(string cadena){
int i;
string final;
for(i=0;i<cadena.length();i++){ if(cadena.at(i)>64 && cadena.at(i)<91)
cadena.at(i) += 32;
//Pasamos el caracter a minusculas

if(letras.find(cadena.at(i))!=-1)
final.apend(cadena.at(i))
//Agregamos a la cadena final el caracter
//si se encuentra en la variable letras

}
return final;
}

PHP

<?php /****************************************************************************** * Nombre : Vigenere.php * Clase para el cifrado de Vigenere para Project-RIC. Este es un cifrado de * sustitución polialfabetico, siendo una variación del cifrado de cesar. La diferencia * es que usa una palabra como semilla, la cual cada caracter representa el indice * del charset a ser sumado en las operaciones modulares. Esta semilla se repita cuantas * veces sea necesario hasta cifrar/descifrar toda la cadena. * @copyLeft  : Project-RIC * @package   : RiCrypt * @author      : D-m-K, [email protected], my.opera.com/d-m-k ******************************************************************************/ class Vigenere { var $charset; var $txt; var $seed; /***************************************************************************** * 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 *                $seed = Cantidad de rotaciones a cada letra ******************************************************************************/ public function __construct($s, $seed) { $this->charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";  //Definicion del charset
$this->txt    = strtoupper($s);
$this->seed   = strtoupper($seed);
}

/************************************************************************************
* Funcion :  encode
* Cifra la cadena pasada como parametro realizando una sustitucion
* polialfabetica a traves de sumas modulares dependiendo el indice de cada caracter de la semilla
* @param  $seed = Semilla con la que sera cifrado el mensaje
* @return $result = Mensaje cifrado
************************************************************************************/
function encode(){
$result = "";                                           //Cadena donde queda el resultado
$x = 0;                                                         //Indice de la semilla
$p = 0;                                                         //Posicion para relizar la operacion modular
for($i=0; $i<strlen($this->txt); $i++){
if(strstr($this->charset, $this->txt{$i})){//Evaluo si existe el caracter en el charset
$x = strpos($this->charset, $this->seed{($p % strlen($this->seed))});
$result .= $this->rotate($this->txt{$i}, $x);   //Invoco funcion que hace la rotacion
$p++; //Aumento el indice para la operacion modular
}else{//Si no existe dejo el caracter evaluado
$result .= $this->txt{$i};
continue;
}
}
return $result;                                         //Devuelvo la cadena Cifrada =)
}

/************************************************************************************
* Funcion  :  decode
* DesCifra la cadena pasada como parametro realizando una sustitucion
* polialfabetica a traves de sumas modulares dependiendo el indice de cada caracter de la semilla
* @param  $seed = Semilla con la que sera cifrado el mensaje
* @return $result = Mensaje cifrado
************************************************************************************/
function decode(){
$result = "";                                           //Cadena donde queda el resultado
$x = 0;                                                         //Indice de la semilla
$p = 0;                                                         //Posicion para relizar la operacion modular
for($i=0; $i<strlen($this->txt); $i++){
if(strstr($this->charset, $this->txt{$i})){//Evaluo si existe el caracter en el charset
$x = strpos($this->charset, $this->seed{($p % strlen($this->seed))});
$result .= $this->rotate($this->txt{$i}, -$x);  //Invoco funcion que hace la rotacion
$p++; //Aumento el indice para la operacion modular
}else{//Si no existe dejo el caracter evaluado
$result .= $this->txt{$i};
continue;
}
}
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
//Realizo la sustitución de cada 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){ $k += $tamC; }else $k %= $tamC; $result .= $this->charset{$k};
}else{
$result .= $c;
}
return $result;
}
}
?>
<?php include 'Vigenere.php';                                 //Incluyo la clase $mensaje   = $_POST['mensaje'];                 //Mensaje a cifrar $semilla   = $_POST['semilla'];                 //Semilla o palabra con la que se cifrara/descifrara el 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 Vigenere($mensaje, $semilla); $salida = $cipher->encode();
}
//DESCIFRADO DEL MENSAJE
if($_POST['tarea'] == "DesCifrar"){
$cipher    = new Vigenere($mensaje, $semilla);
$salida = $cipher->decode();
}
}
?>
<html>
<head>
<title> .:: Implementacion de la cifra de vigenere ::. </title>
</head>
<body>

<h1>Vigenere</h1>
<hr>

<!-- Datos para el cifrado -->

<form method="post">
<strong>Mensaje a cifrar / descifrar :</strong> 
<textarea name="mensaje" style="width:500px;border:1px solid #555"><?php echo $_POST['mensaje']; ?></textarea>
<strong>Semilla :</strong>
<input type="text" name="semilla" style="width:150px;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> 
 \n";
echo "
<div class='mensaje'>" . $salida . "</div>

";
}
?>
</body>
</html>

2 Comentarios

  1. Responder

    Buenos días, gracias por su ayuda, tengo una duda, cuando monto el código en DevC++, me aparece un error en la primera linea, donde dice public class vigenere{ , si me podrías ayudar, gracias 🙂

  2. Responder

    Me marca el mismo error que comentar de la primer linea

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>