Thread: XOR encryption

  1. #1
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964

    XOR encryption

    I've been trying to get this simple encryption application to work, but i keep getting the wrong output.

    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    #include "clscr.h"
    
    int main()
    {
        std::ofstream outputfile ("C:\\WINDOWS\\XOR\\DATA.txt", std::ios::trunc);
        
        std::string key, plainText, cipherText;
        int i = 0, j = 0, k = 0, l = 0;
        
        std::cout << "Enter key: ";
        std::cin >> key;
        
        std::cout << std::endl << "Enter plaintext: ";
        std::cin >> plainText;
        clscr();
        
        i = plainText.length();
        l = key.length();
        
        for(j; j < i; j++)
        {
               cipherText[j] = plainText[j] ^ key[k];
               k++;
               
               if(k == (l+1))
               {
                    k = 0;
               }
        }
        
        for(j = 0; j < i; j++)
        {
              outputfile << cipherText[j];
        }
        std::cin.ignore();
        outputfile.close();
    }
    I get the wrong number of characters in the text-file, but i've gone through the code a hundred times, and i can't find the error. What have i done wrong?

  2. #2
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Forgetting about the line-break perhaps ?

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Have you tried just doing
    cipherText[j] = plainText[j];
    to make sure you can actually copy the data without any transformations.

    > std::cin >> plainText;
    You realise that this will stop at the first space right?
    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.

  4. #4
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    Quote Originally Posted by Salem View Post
    > std::cin >> plainText;
    You realise that this will stop at the first space right?
    No, i didn't realize that. How do i get the user input into my string without it breaking at spaces?

    When cout'ing the cipherText i get the correct output, but when i look at it in notepad it just shows up as squares. I guess it's because notepad has a hard time displaying beeps and smileys, how do i get the program to ignore those abnormal characters? Or is that even necessary?

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Use getline()
    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.

  6. #6
    Sanity is for the weak! beene's Avatar
    Join Date
    Jul 2006
    Posts
    321
    You will have to use:
    Code:
    std::cin.getline(plainText,1000);
    I think...

  7. #7
    Registered User
    Join Date
    Nov 2005
    Posts
    673
    or you could simply use
    Code:
    std::getline(std::cin, plainText);
    //or
    std::getline(std::cin, plainText, '\n');
    He is a simple function to use XOR to encrypt a file, all you have to do is hardcode your key
    Code:
    struct CRYPT_
    {
        char* byte;
        std::string key;
    };
    
    //here is the function
    CRYPT_ data;
    bool Crypt(const std::string& file)
    {
        data.byte = new char;
        char* savebyte = new char;
        int value = 0;
        data.key = "!+_@)#($*&#37;&^-=,./'\"][}{|:\\<>?~`";
        ifstream load (file.c_str(), ios::binary);
        if (!load)
        {
            return false;
        }
        ofstream save ("encrypted.xtc", ios::binary);
        while (load.get(*data.byte))
        {
            *savebyte = *data.byte ^ data.key[value];
            save << *savebyte;
            if ( value < 30 )
            {
                ++value;
            }
            else
            {
                value = 0;
            }
        }
        save.close();
        load.close();
        remove(file.c_str());
        rename("encrypted.xtc", file.c_str());
        delete data.byte;
        delete savebyte;
        return true;
    }
    I hope that helps. It is a relatively basic function, but easy to complicate more if you needed.
    Last edited by Raigne; 06-11-2007 at 01:29 PM. Reason: typo

  8. #8
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    > if(k == (l+1))
    This should be:
    Code:
               if (k == l)
    > if ( value < 92 )
    This will go way past the end of the string.

  9. #9
    Registered User
    Join Date
    Nov 2005
    Posts
    673
    sorry that was a mistake, because the 92 is for the key that I use. I just replaced the string with random characters.

  10. #10
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >sorry that was a mistake, because the 92 is for the key that I use.
    Aye, I was wondering because other than that the code looked ok. Of course an alternative is:
    Code:
            if ( value < data.key.length() )
    Or the equivalent:
    Code:
            if ( value < data.key.size() )

  11. #11
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    I guess it would really be:
    Code:
            if ( value+1 < data.key.length() )
    Since you haven't incremented value yet.

  12. #12
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    Quote Originally Posted by swoopy View Post
    > if(k == (l+1))
    This should be:
    Code:
               if (k == l)
    No it shouldn't, the k variable is incremented after i do the XOR'ing, and then i check the size, so if i do "if(k == l)" it won't use the last character in the key.

    Anyways, it works with the spaces now using getline, thanks alot guys

  13. #13
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Quote Originally Posted by Neo1 View Post
    No it shouldn't, the k variable is incremented after i do the XOR'ing, and then i check the size, so if i do "if(k == l)" it won't use the last character in the key.
    Actually you're stepping one past the key's end.

  14. #14
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    Quote Originally Posted by swoopy View Post
    Actually you're stepping one past the key's end.
    If my code is 10 digits long, and k starts at 0, then it will loop once, then increment and check the size, it will keep doing this until k reaches 9, then it will loop and increment the variable, so k is now 10, k will still not be big enough because if it stopped now, it still hasn't used the last digit.

    I increment after i apply the key, and i check the size after i increment it, so if i stop at 10, i won't get to apply the 10th digit of the key, unless i loop one more time.

  15. #15
    Registered User
    Join Date
    Nov 2005
    Posts
    673
    What?
    if it is 10 digits long, and you start at 0. then you stop at 9. Don't forget everything ( for the most part ) starts at zero in C++.

Popular pages Recent additions subscribe to a feed