Playfair

Iniciado por deni_celine, Marzo 04, 2014, 08:34:13 AM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Marzo 04, 2014, 08:34:13 AM Ultima modificación: Marzo 04, 2014, 05:04:38 PM por deni_celine
Estaba en esto de querer aprender c plus plus y alguien me recomendo que hiciera este cifrado como ejercicio, dejo el código por si a alguien le sirve o mejor aún si a alguien se le ocurre una forma mejor

El cifrado playfair es ... bueno, es complicado de explicar, ya que va sustituyendo de a pares, usando una matriz de 5 x 5 que es generada por una clave y que contiene las letras del abecedario, salvo una , ya que son 26 letras y 5 x5 = 25, y despues aplica al mensaje un par de reglas para hacer la sustitución... mucho mejor les dejo el link a la wikipedia :D No tienes permitido ver los links. Registrarse o Entrar a mi cuenta y en esta página puedes verlo en funcionamiento No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Código: cpp

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

class PlayFair{
  private:
    char matriz[5][5];
  public:
    string cifrado(string, int);
    string descifrar(string);
    int inMatriz(char);
    void limpiaMatriz();
    void setMatriz(string);
    void showMatriz();
};

int main(){
  string clave,msj;
  PlayFair pf;

  cout << "Cifrado PlayFair"<<endl<<endl;
  cout << "introduce la clave > ";
  //getline(cin,clave);
  clave = "playfairexample";
  cout <<endl;

  pf.setMatriz(clave);
  pf.showMatriz();

  cout << endl;
  cout << "introduce el mensaje a cifrar > ";
  getline(cin,msj);

  string cifrado = pf.cifrado(msj,1);
  cout << "Mensaje cifrado : " << cifrado << endl;
  cout << "Msj. descifrado : " << pf.cifrado(cifrado,2) << endl;

}


int PlayFair::inMatriz(char valor){
    for(int i=0;i<5;i++){
      for(int j=0;j<5;j++){
        if(matriz[i][j] == valor){
          return 1;
        }
      }
    }
    return 0;
}

void PlayFair::limpiaMatriz(){
  for(int i=0;i<5;i++){
    for(int j=0;j<5;j++){
      matriz[i][j] = ' ';
    }
  }
}

void PlayFair::setMatriz(string clave){
  PlayFair::limpiaMatriz();
  int i=0;
  int j=0;
  //coloca la clave en la matriz
  for(int a=0;a<clave.size();a++){
    if(PlayFair::inMatriz(clave[a]) == 0)
      matriz[i][j++] = tolower(clave[a]);
    if (j==5){
      j = 0;
      i++;
    }
  }
  char abc[26]={'a','b','c','d','e','f','g','h','i','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
  //termina llenar la matriz con el abecedario
  for(int a=0;a<26;a++){
    if(PlayFair::inMatriz(abc[a]) == 0)
      matriz[i][j++] = abc[a];
    if (j==5){
      j = 0;
      if(i==5){
        continue;
      }
      i++;
    }
  }
}

/*
Metodo cifrado -> tipo 1: cifrar, tipo 2: desifrar
*/
string PlayFair::cifrado(string msj, int tipo=1){
  string result,msj2;

  //Verifica que el mensaje este en la matriz, si 2 caracteres se repiten pone una 'x' en medio, y pasa a minusculas.
  char ant;
  for(int i=0;i<msj.size();i++){
      for(int x=0;x<5;x++){
        for(int y=0;y<5;y++){
          if(matriz[x][y]==tolower(msj[i])){
            if(msj[i]==ant){
                msj2 += "x";
            }
            msj2 += tolower(msj[i]);
            ant = tolower(msj[i]);
          }
        }
      }
  }
  msj = msj2;
  //Si el largo del mensaje es impar, agrega una 'x' al final.
  if ((msj.size()%2)!=0){
    msj += "x";
  }

  //Recorre el msj
  for(int i=0;i<msj.size();i++){
    int j= i+1;
    int pos_x1 = 0;
    int pos_y1 = 0;
    int pos_x2 = 0;
    int pos_y2 = 0;
    int flag = 0;
    int in_fila = 0;

    // verifica caracteres en horizontal
    for(int x=0;x<5;x++){
      for(int y=0;y<5;y++){
        if(matriz[x][y]== msj[i]){
          pos_x1 = x;
          if(tipo ==1){
              if(y<4){
                pos_y1 = y+1;
              }
              else{
                pos_y1 = 0;
              }
          }
          else{
              if(y>0){
                pos_y1 = y-1;
              }
              else{
                pos_y1 = 4;
              }
          }
          in_fila++;
        }
        if(matriz[x][y]== msj[j]){
          pos_x2 = x;
          if(tipo ==1){
              if(y<4){
                pos_y2 = y+1;
              }
              else{
                pos_y2 = 0;
              }
          }
          else{
              if(y>0){
                pos_y2 = y-1;
              }
              else{
                pos_y2 = 4;
              }
          }
          in_fila++;
        }
      }
      if (in_fila == 2){
        flag = 1;
      }
      in_fila = 0;
    }

    // verifica caracteres en vertical
    if (flag==0){
        for(int y=0;y<5;y++){
          for(int x=0;x<5;x++){
            if(matriz[x][y]== msj[i]){
              pos_y1 = y;
              if(tipo==1){
                if(x<4){
                    pos_x1 = x+1;
                }
                else{
                    pos_x1 = 0;
                }
              }
              else{
                  if(x>0){
                    pos_x1 = x-1;
                  }
                  else{
                    pos_x1 = 4;
                  }
              }
              in_fila++;
            }
            if(matriz[x][y]== msj[j]){
              pos_y2 = y;
              if(tipo==1){
                if(x<4){
                    pos_x2 = x+1;
                }
                else{
                    pos_x2 = 0;
                }
              }
              else{
                  if(x>0){
                    pos_x2 = x-1;
                  }
                  else{
                    pos_x2 = 4;
                  }
              }
              in_fila++;
            }
          }
          if (in_fila == 2){
            flag = 1;
          }
          in_fila = 0;
        }
    }

    //verifica rectangulos
    if (flag==0){
      for(int x=0;x<5;x++){
        for(int y=0;y<5;y++){
          if(matriz[x][y]== msj[i]){
            pos_x1 = x;
            pos_y2 = y;
          }
          if(matriz[x][y]== msj[j]){
            pos_x2 = x;
            pos_y1 = y;
          }
        }
      }

    }

    result += toupper(matriz[pos_x1][pos_y1]);
    result += toupper(matriz[pos_x2][pos_y2]);
    result += " ";

    i++;
  }
  return result;
}


void PlayFair::showMatriz(){
  //muestra la matriz
  for(int i=0;i<5;i++){
    for(int j=0;j<5;j++){
      cout << PlayFair::matriz[i][j];
    }
    cout << endl;
  }
}


que cifrado es ese? podrias explicar un poco mejor como va todo el programa y todo eso xD
la verdad es que sabes mucha mas programacion que yo (soy muy novato)
RollthBuen hacker mejor No tienes permitido ver los links. Registrarse o Entrar a mi cuenta/No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Tienes razón faltaba un poquito explicar que hacía jejje, pero en la Wiki esta bien explicado el cifrado en si, si tienes alguna duda respecto al programa me preguntas, antes programaba en otros lenguajes pero en c++ tb soy noob :D, aunque la mayoría de los lenguajes se parecen de alguna u otra forma

He hecho un copypaste y la verdad el programa no me funciona del todo bien, solo me sale
me sale esto directamente


y cuando pongo la clave se va sin decirme la solucion
RollthBuen hacker mejor No tienes permitido ver los links. Registrarse o Entrar a mi cuenta/No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

esta tomando una clave por default que es 'playfair example' , si descomentas la linea 25 y comentas la 26 podrás cambiar la clave , y si tienes razón se cierra sin mostrar el resultado es que lo estaba ejecutando de la consola xd , si estas en windows ponele SYSTEM("PAUSE"); al final, onda línea 39

vale xD, pero estaria bien que el programa le pidiera al usuario la clave.
RollthBuen hacker mejor No tienes permitido ver los links. Registrarse o Entrar a mi cuenta/No tienes permitido ver los links. Registrarse o Entrar a mi cuenta