1

I'm doing a vigenere encrypting in console. First I did the generation of random position in an alphabet of 37 characters. By the way, I'm using visual studio. I tried with some other messages and keys that my classmates gave me and my code worked. I mean that I got the original message from the encrypted message using the key that they gave me.

All the code works, however I have the problem with the space " " because when I use the key generated, It interpretes the space as "a" (the first caracter) I have been trying with some solutions that the teacher gave me, but even she didn't understand what was the problem. She is a Phd from Brasil. I have a good grade because, apparently, the code should run correctly.

int main()
{
    string abecedario = "abcdefghijklmnopqrstuvwxyz0123456789 "; //la cadena que almacena el abecedario predeterminado
    cout << abecedario.length();
    string mensaje; //la cadena que almacenara el mensaje

    cout << "Ingrese el mensaje: " << endl;
    getline(cin, mensaje); //usamos el comando getline para ingresar el mensaje para tener el espacio tambien

    int tam = mensaje.length();
    srand(time(NULL));          
    int aleatorio;

    vector <string> posiciones;     //Esta cadena son las posiciones de las letras para tener, despues, el mensaje cifrado

    for (int i = 0;i < tam;i++) {
        aleatorio = (rand()+rand()+rand())%37; //generamos un numero aleatorio para posiciones sub i, dividido entre el tamaño del string para no exceder el limite
        string alt = to_string(aleatorio); //transformamos el numero a un char
        posiciones.push_back(alt); //insertamos el char en la cadena
    }
    cout << "Estas son las posiciones: " << endl;
    for (int i = 0; i < tam; i++) {
        cout  << posiciones[i] << " " ;
    }
    cout << endl;
    string clave = ""; //la clave del string la iniciamos en una cadena vacia

    for (int i = 0;i < tam;i++) {
        int temp;
        stringstream pos(posiciones[i]);
        pos >> temp;
        clave = clave + abecedario[temp];
    }
    cout << "La clave es: " << endl << clave << endl;

    int* arrow = new int[tam]; //creamos un arreglo de enteros para almacenar
    for (int i = 0;i < tam;i++) {
        int n1;
        int n2;
        for (int k = 0; k < abecedario.size();k++) {
            if (abecedario[k] == mensaje[i]) {       // recorremos el abecedario y recorremos los valores hasta que este sea igual a mensaje sub i
                n1 = k;                              // si la anterior condicion es verdadera igualamos n1 a esa parte de la cadena
            }
        }
        for (int t = 0; t < abecedario.size();t++) {
            if (abecedario[t] == clave[i]) {        // usamos la misma iteracion anterior, pero en vez de mensaje sub i, lo comparamos con clave sub i
                n2 = t;                             // esta vez si la condicion se cumple igualamos n2 a esa parte de la cadena
            }
        }
        if (n1 + n2 < 37) {
            arrow[i] = (n1 + n2);// almacenamos la suma de n1 y n2 en arrow 
        }
        else {
            arrow[i] = (n1 + n2) - 36;
        }
    }

    string mensajeCifrado = ""; // creamos un string para almacenar el mensaje cifrado

    for (int i = 0;i < tam;i++) {
        int l = arrow[i]; // igualamos una variable l a arrow sub i 
        mensajeCifrado = mensajeCifrado + abecedario[l]; // almacenamos en mensajeCifrado el caracter abecedario sub l
    }
    cout << "El mensaje cifrado es: " << endl;
    cout << mensajeCifrado;
    string mensajeNuevo = "";
    for (int i = 0; i < mensajeCifrado.length();i++) {
        int pos1;
        pos1 = abecedario.find(mensajeCifrado[i]) - abecedario.find(clave[i]);
        if (pos1 < 0) {
            mensajeNuevo = mensajeNuevo + abecedario[pos1+36];
        }
        else{
            mensajeNuevo = mensajeNuevo + abecedario[pos1];
        }
    }
    cout << endl << "Este es el mensaje: " << endl;
    cout << mensajeNuevo;
}
Maarten Bodewes
  • 80,169
  • 13
  • 121
  • 225
  • Do you know that there is a [Spanish StackOverflow](https://es.stackoverflow.com/) as well? Because I find C++ code confusing enough without having to translate, to be honest. – Maarten Bodewes Sep 03 '19 at 00:36
  • 2
    There are a lot of things such as integer pointers and stringstreams that seem unnecessary for implementing Vigenere, and no functions defined. It is important to split up functionality in functions, and test the functions separately instead of trying to do things all in one go (by general principle, not just for this one thing). Having a single main just doesn't do; that way it is hard to debug stuff. – Maarten Bodewes Sep 03 '19 at 00:41
  • `arrow[i] = (n1 + n2) - 36` seems suspicious, changing to `37` seems to solve your issue [Demo](https://ideone.com/5UK3jY) – Jarod42 Sep 03 '19 at 00:48
  • 1
    And so avoid magic values as `36`, `37`, `38`. Use constant as `alphabet_size`. – Jarod42 Sep 03 '19 at 01:15
  • With split functions, it might be something like: [that](https://ideone.com/RZhc3b). and each function can easily be tested. (`encrypt(alphabet, "a")` for example should be identity). – Jarod42 Sep 03 '19 at 01:17
  • This code probably could use some debugging on your end so that you can present a smaller, simpler bit of code that demonstrates the problem (c.f. [mcve]). There is one debugging trick that I've picked up and that seems to apply here: move the space to the start of the string (as in `string abecedario = " abcdefghijklmnopqrstuvwxyz0123456789"`). If the problematic character is now the `9`, you are likely off-by-one in a length calculation somewhere. – JaMiT Sep 03 '19 at 02:30
  • I tried to put the space character on other position. The bug now is with the character: '9'. I have been putting a lot of different lenghts and the bug is still there. – Armando Miguel Zegarra Castill Sep 04 '19 at 01:12
  • @ArmandoMiguelZegarraCastill To emphasize a comment by Jarod42: [What are “symbolic constants” and “magic constants”?](https://stackoverflow.com/questions/43950998/what-are-symbolic-constants-and-magic-constants) In this case, the symbolic constant should be initialized to `abecedario.length()`, so there should be no need to manually put in a length. – JaMiT Sep 04 '19 at 03:09

0 Answers0