Crashing Vigenere Cipher program

This is a discussion on Crashing Vigenere Cipher program within the C++ Programming forums, part of the General Programming Boards category; I made a program to encode and decode messages using a Vigenere Cipher and a key. (if you dont know ...

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    37

    Unhappy Crashing Vigenere Cipher program

    I made a program to encode and decode messages using a Vigenere Cipher and a key. (if you dont know what a Vigenere Cipher is... then check Wikipedia.) It should work *fine*, but it keeps hanging at the point when it should show the encrypted message/decrypted message.

    Code:
    #include<iostream>
    #include<windows.h>
    using namespace std;
    class Frame
    {
     public:
            char square();
            int enc();
            int dec();
    };
    char Frame::square()
    {
        // ===(Vigenere Square Generator)===
        char a[26][26], alpha='a', flag='a', showvig;
        for(int col=0; col<26; col++)
        {
                for(int row=0; row<26; row++)
                {
                        a[col][row]=alpha;               //'a[][]' is assigned alpha's value
                        alpha++;                         //Alpha increased
                        if(alpha>'z')
                                     alpha='a';          //continues the series after z
    //                  cout<<a[col][row]<<" ";          //optional display statement
                }
                flag++;                                  //Value of flag increased
                alpha=flag;                              //Value of flag assigned to a
        }
    /*    cout<<"\nDisplay Vigenere Square?(Y/N) ";
        cin>>showvig;
        if(showvig=='Y' || showvig=='y')
        {
            for(int col=0; col<26; col++)
            {
                for(int row=0; row<26; row++)
                {
                    cout<<a[col][row]<<" ";
                }
                cout<<endl;
            }
        } */
        return a[26][26];   
    }
    int Frame::enc()
    {   
        char b[26][26];
        b[26][26]=square();
        // ===(ACME Encrypt O Matic)===
        char key[50], srchk, srchm, message[100], encoded[100];
        int keylen, msglen, arow, bcol, k;
        cout<<"\nEncrypter ready";
        cout<<"\nInsert key... ";
        cin.getline(key,50);
        cin.getline(key,50);
        cout<<"\nShowing the key..... "<<key<<key<<key;  //Comparison purposes
        cout<<"\nEnter the message... ";
        cin.getline(message,100);
        keylen=strlen(key);
        msglen=strlen(message);
        cout<<"\nEncrypted message... ";
        for(int i=0; i<msglen; i++)
        {
                k=i;                                    //Allows for the messages
                if(i>keylen)                            //to be longer than the
                            k=0;                        //key ie repeating key behaviour
                srchk=key[k];
                srchm=message[i];
                if(message[i]==' ')
                {
                            encoded[i]=' ';
                            goto label;
                }
                for(int col=0, row=0; col<26; col++)
                {
                        if(srchk==b[row][col])
                        {
                                              bcol=col;
                                              break;
                        }
                }
                for(int row=0, col=0; row<26; row++)
                {
                           if(srchm==b[row][col])
                           {
                                                 arow=row;
                                                 break;
                           }
                }
                encoded[i]=b[arow][bcol];
                label:
                cout<<encoded[i];
        }
        cout<<endl;
        system("PAUSE");
        return 0;
    }
    int Frame::dec()
    {    
         char c[26][26];
         c[26][26]=square();
        // ===(ACME Encryption-Be-Gone)===
         char key[50], srchk, srchm, message[100], encoded[100];
         int keylen, msglen, arow, bcol, k;
         cout<<"\nInitializing...";
         Sleep(5);
         cout<<"\nDecrypter ready";
         cout<<"\nInsert key... ";
         cin.getline(key,50);
         cin.getline(key,50);
         cout<<"\nShowing the key..... "<<key<<key<<key;  //Comparison purposes
         cout<<"\nEnter coded mssg.... ";
         cin.getline(encoded,100);
         keylen=strlen(key);
         msglen=strlen(encoded);
         cout<<"\nDecrypted message... ";
         for(int i=0; i<msglen; i++)
         {
                 k=i;                                    //Allows for the messages
                 if(i>keylen)                            //to be longer than the
                             k=0;                        //key ie repeating key behaviour
                 srchk=key[k];
                 srchm=encoded[i];
                 if(encoded[i]==' ')
                 {
                             message[i]=' ';
                             goto label2;
                 }
                 for(int col=0, row=0; col<26; col++)
                 {
                         if(srchk==c[row][col])
                         {
                                               bcol=col;
                                               break;
                         }
                 }
                 for(int row=0, col=bcol; row<26; row++) //col=0 changed
                 {
                            if(srchm==c[row][col])
                            {
                                    col=0;
                                    bcol=col;
                                    arow=row;
                                    break;
                            }
                 }
                 message[i]=c[arow][bcol];
                 label2:
                 cout<<message[i];
         }
         cout<<endl;
         system("PAUSE");
         return 0;
    }
    int main()
    {
        Frame ob;
        int ch;
        cout<<"\n(1)Encrypt or (2)decrypt?";
        cin>>ch;
        if(ch==1)
                 ob.enc();
        else
            if(ch==2)
                     ob.dec();
        return 0;
    }
    What exactly is t3h problem? It worked fine when I ran the encrypt/decrypt sections separately (by putting all the code in just the main(), and putting comments on the encrypt or decrypt sections)

    -regards,
    ultrabot90
    Last edited by ultrabot90; 09-21-2007 at 09:09 AM.

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    >> return a[26][26];
    You can't return arrays like that. Instead of returning the array, make a parameter for the function that is char a[26][26] and remove the local a array. Then just pass in the c array when you call the function and it will get updated appropriately.

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    It seems to me (after trying out your code) that you use variables that are undefined, e.g.:
    Code:
    			encoded[i]=b[arow][bcol];
    arow is some huge value (Perhaps I'm doing something wrong in using the code tho').

    I'm also pretty sure that you need to do this differently:
    Code:
    		k=i;                                    //Allows for the messages
    		if(i>keylen)                            //to be longer than the
    			k=0;                        //key ie repeating key behaviour
    		srchk=key[k];
    If you give "KEY" as the key, then after the third letter, it will just repeat "KKKKKKKKKKKKK" until the end of the message, which is of course not particularly good encryption (could just as well use cesars cipher in that case).

    You probably want to do:
    Code:
     k++;                                    //Allows for the messages
    		if(k>keylen)                            //to be longer than the
    			k=0;                        //key ie repeating key behaviour
    		srchk=key[k];

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Also
    Code:
    	return a[26][26];
    That returns the 27th column of the 27th row! - You only have 26 of each.

    Of course, looking further at your code, it seems like you actaully want to return the FULL 2D array.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Sep 2007
    Posts
    37
    @Daved - That indeed seems to be the problem...I've edited it, though I dunno if I did it right...
    Code:
     public:
            void square();
            int enc(char[26][26]);
            int dec(char[26][26]);
    };
    Code:
    void Frame::square()
    {
        // ===(Vigenere Square Generator)===
        char a[26][26], alpha='a', flag='a', showvig;
    Code:
    int Frame::enc(char b[26][26])
    {   
        // ===(ACME Encrypt O Matic)===
        char key[50], srchk, srchm, message[100], encoded[100];
    Code:
    int Frame::dec(char b[26][26])
    {    
         // ===(ACME Encryption-Be-Gone)===
    Code:
    int main()
    {
        Frame ob;
        int ch;
        cout<<"\n(1)Encrypt or (2)decrypt?";
        cin>>ch;
        if(ch==1)
                 ob.enc(char[][]);
        else
            if(ch==2)
                     ob.dec(char[][]);
        return 0;
    }
    In the main(), however, it gives errors for both of the enc() and dec() functions, that "expected primary-expression before "char"". Now what do I do?

    @matsp- Omg no, that part is correct, 100&#37;! I've already said that it works fine when running individual encode/decode functions.
    On the key repeating lines...
    The key is supposed to be written on top of the message, again and again, so that every letter of the message matches up with a key letter it is to be encoded with. Hence, both key and message run with [i], simultaneously, on untill the message to be encoded/decoded ends (in key[k] I made an exception, lets see why ->). As soon as i becomes greater than the key length, k resets to 0, and since key is working according to k, it repeats...Simple! ^_^

    arow and bcol are just used to store the 'coordinates' of the required character which is to be input into the encoded/decoded message. arow and bcol arent huge, they're both less than 26 xD
    EDIT - Omg the second thing hell thats true it'd return a[26][26]th element! Sheesh...
    -regards,
    ultrabot90
    Last edited by ultrabot90; 09-21-2007 at 09:45 AM.

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    You got it backwards. You want to have square take the parameter and the other functions pass in the arrays they create.

  7. #7
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,485
    Why not leave the array inside the class as a private member variable, and save all this messing about passing the array in and out every time you want to do something.

    And can I just say "ugh" to the goto's.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Gotos should go... Especially since the goto is fairly easy to get rid of by just using an "else" at the end of the if which contaisn the goto (and of course braces around the code down to the line before the now defunct label).

    I also agree on the use of square as a member of the class.

    By the way, your code only works right if the key and message are lower-case. Maybe you want to add
    Code:
    		srchk=tolower(key[k]);
    and corresponding on srchm.

    If you add the red bit:
    Code:
    	cin>>ch;
    	cin.ignore();
    
    you don't have to do two getline's (because the "ignore" bit will "eat" the newline that is otherwis sitting there and making key an empty string.

    Of course, it's all broken for non-alpha characters, so perhaps your lines
    Code:
    		if(encoded[i]==' ')
    		{
    			message[i]=' ';
    should be:
    Code:
    		if(!isalpha(encoded[i]))
    		{
    			message[i]= encoded[i];
    And of course the corresponding code in encode.

    The for-loops that you use for searching in the encode can be easily replaced with simple math:
    Code:
        bcol = srchk - 'a';
        arow = srchm - 'a';
    .
    And the bcol can be done the same way in the decode part.


    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,799
    Quote Originally Posted by Salem
    Why not leave the array inside the class as a private member variable, and save all this messing about passing the array in and out every time you want to do something.
    Yeah, that's something I would also suggest, have the table exist as a private data member. And it looks like you recreate the table each time you encrypt/decrypt something. Do it once (put the code that builds the table in the constructor for example) and access that table directly from the enc and dec functions, no need to pass it around anymore. You can ditch the square function then as well.

    Code:
    class Frame
    {
        char a[26][26];
     public:
        //char square();  // Ditch this
        Frame();  // Add this
        int enc();
        int dec();
    };
    
    Frame::Frame()  // Builds the table
    {
        for( int col=0; col<26; ++col )
            for( int row=0; row<26; ++row )
                a[col][row] = 'a' + ((col+row)%26);
    }
    Then you can get rid of the b and c arrays in enc and dec and just use the a array everywhere instead.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  10. #10
    Registered User
    Join Date
    Sep 2007
    Posts
    37
    Omg, ideas nothing short of genius, specially that
    Code:
        bcol = srchk - 'a';
        arow = srchm - 'a';
    part. And hey, how about putting the key, srchk, srchm, message, encoded, keylen, msglen, arow and bcol in the private section? Its down from ~150 lines to 99...cool.
    Now, in sync with the newly learnt stuff...
    Code:
    #include<iostream>
    #include<windows.h>
    using namespace std;
    class Frame
    {
     private:
             char a[26][26], key[50], srchk, srchm, message[100], encoded[100];
             int keylen, msglen, arow, bcol, k;
     public:
            Frame()
            {
                   for( int col=0; col<26; ++col )
                        for( int row=0; row<26; ++row )
                             a[col][row] = 'a' + ((col+row)%26);
            }
            int enc();
            int dec();
    };
    int Frame::enc()
    {   
        // ===(ACME Encrypt O Matic)===
        cout<<"\nEncrypter ready ";
        cout<<"\nInsert key... ";
        cin.getline(key,50);
        cout<<"\nShowing the key..... "<<key<<key<<key;
        cout<<"\nEnter the message... ";
        cin.getline(message,100);
        keylen=strlen(key);
        msglen=strlen(message);
        cout<<"\nEncrypted message... ";
        for(int i=0; i<msglen; i++)
        {
                k=i;
                if(i>keylen)
                            k=0;
                srchk=tolower(key[k]);
                srchm=tolower(message[i]);
                if(!isalpha(message[i]))
                            encoded[i]=message[i];
                else
                {
                    bcol = srchk - 'a';
                    arow = srchm - 'a';
                    encoded[i]=a[arow][bcol];
                }
                cout<<encoded[i];
        }
        cout<<endl;
        system("PAUSE");
        return 0;
    }
    int Frame::dec()
    {    
         // ===(ACME Encryption-Be-Gone)===
         cout<<"\nDecrypter ready ";
         cout<<"\nInsert key... ";
         cin.getline(key,50);
         cout<<"\nShowing the key..... "<<key<<key<<key;
         cout<<"\nEnter coded mssg.... ";
         cin.getline(encoded,100);
         keylen=strlen(key);
         msglen=strlen(encoded);
         cout<<"\nDecrypted message... ";
         for(int i=0; i<msglen; i++)
         {
                 k=i;
                 if(i>keylen)
                             k=0;
                 srchk=tolower(key[k]);
                 srchm=tolower(encoded[i]);
                 if(!isalpha(encoded[i]))
                                         message[i]= encoded[i];
                 else
                 {
                     bcol = srchk - 'a';
                     arow = srchm - 'a';
                     message[i]=a[arow][bcol];
                 }
                 cout<<message[i];
         }
         cout<<endl;
         system("PAUSE");
         return 0;
    }
    int main()
    {
        Frame ob;
        int ch;
        cout<<"\n(1)Encrypt or (2)Decrypt?";
        cin>>ch;
        cin.ignore();
        if(ch==1)
                 ob.enc();
        else
            if(ch==2)
                     ob.dec();
        return 0;
    }
    Guess what...it still crashes. What could possibly be the problem? -_-

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Doesn't crash on my machine. What do you do to crash it?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Registered User
    Join Date
    Sep 2007
    Posts
    37
    Quote Originally Posted by matsp View Post
    Doesn't crash on my machine. What do you do to crash it?

    --
    Mats
    Dunno, I run encode, put in a short (7 letter) key, type in a message usually being shorter than the key, and it crashes. Machine is Intel P4 1.72 GHz, 256 MB SDRAM, atleast 12/40 gb HDD space free, running Windows XP Pro SP2, onboard 32 mb gfx card. Do I need to give the error details (!!!) next? o.o

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    What key do you give it? If you don't want to post the key you're using, find another that causes the crash that you can post.

  14. #14
    Registered User
    Join Date
    Sep 2007
    Posts
    37
    It ran, but with decryption errors...
    With key as "systemofadown" it encrypts "omfg wtf" as "gkxz ihk"...but decrypts the same as "yips uvp".
    Last edited by ultrabot90; 09-21-2007 at 12:37 PM.

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, you are doing "encryption" in the decryption part. Unfortunately, [I don't think, at least] you can't remove the loop bit out of the decode part.

    Replacing the
    Code:
    arow = srchm - 'a'
    with:
    Code:
    				for(int row=0; row<26; row++) //col=0 changed
    				{
    							if(srchm==a[row][bcol])
    							{
    									arow=row;
    									break;
    							}
    				}
    gives this:
    Code:
    (1)Encrypt or (2)Decrypt?1
    
    Encrypter ready
    Insert key... hello
    
    Showing the key..... hellohellohello
    Enter the message... abc
    
    Encrypted message... hfn
    
    (1)Encrypt or (2)Decrypt?2
    
    Decrypter ready
    Insert key... hello
    
    Showing the key..... hellohellohello
    Enter coded mssg.... hfn
    
    Decrypted message... abc
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help with my program...
    By Noah in forum C Programming
    Replies: 2
    Last Post: 03-11-2006, 06:49 PM
  2. Substitution Cipher Program Problem...
    By Junior89 in forum C++ Programming
    Replies: 13
    Last Post: 12-28-2005, 04:02 PM
  3. cipher program need alil help
    By Uber Fr0g in forum C Programming
    Replies: 3
    Last Post: 12-14-2005, 06:38 PM
  4. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21