Thread: Problems with Xor encryption

  1. #1
    the magic penguim
    Join Date
    Jul 2005
    Posts
    91

    Problems with Xor encryption

    Hey guys, I'm trying to develop a Xor ecnryption function but I'm having some problems...

    Here's what I've so far:

    Code:
    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
        char string[] = "This is a test!!!";
        char key[] = "123";
    
        XorEncrypt (&string, &key);
        
        printf("%s", string); 
        getch();
        return 0;
    }
    
    int XorEncrypt (char *string, char *key)
    {
        int cnt = 0, i, j, r, mod;
        
        int StringLen = strlen(string); // 20
        int KeyLen = strlen(key); // 6
        
        r = StringLen / KeyLen;
        
        for (i = 0; i < r; i++)
        {
            for (j = 0; j < KeyLen; j++)
            {
                string[i*KeyLen + j] = string[i*KeyLen + j] ^ key[j];
            }
        }
        
        mod = StringLen % KeyLen;
        
        if ( mod != 0)
        {
             for (i = 0; i < mod; i++)
             {
                 string[-mod + i] = string[-mod + i] ^ key[i];
             }
        }
        
        return 0;
    }
    Output: eZZB↕ZB↕R◄FVBF↕!!


    The function is not working tough, if I take that output and pass it again to the function I get this:

    a♫test♀!!

    I don't know if I made a mistake regarding pointers or if there's something wrong in the function itself... Please help =)

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by lala123 View Post
    The function is not working tough, if I take that output and pass it again to the function I get this:
    How are you passing the input back? Copy and paste? If so, the copy/paste is probably screwing up the values. I don't see anything wrong with the encryption code itself, so I think you are having some other issue here.

    Also, you can't use printf() to display the result. The XOR encryption might have caused a byte to become zero, which in C indicates "end of string." You need to remember how long the string was before you encrypted it, and print exactly that many characters.

    Printing encrypted data to a terminal is usually a bad idea, since it may contain control characters that confuse the terminal. I bet if you change your program to read/write its data from files instead of the console, it will suddenly work much better.

  3. #3
    the magic penguim
    Join Date
    Jul 2005
    Posts
    91
    Thank you for your quick response buck. I tried doing as you said, but for some reason the text at the file remains unchanged...

    Here's what I'm using:

    Code:
    #include <stdio.h>
    
    int main(int argc, char *argv[])
    {
        FILE *fp;
        long fSize;
        size_t result;
        char key[] = "123", *buffer;
    
        fp = fopen ("xor.txt", "rb+");
        
        if (fp == NULL)
           {fputs("File error",stderr); exit(1);}
           
        fseek (fp, 0, SEEK_END);
        fSize = ftell (fp);
        rewind (fp);
        
        buffer = (char*) malloc (sizeof(char)*fSize);
        
        if (buffer == NULL)
           {fputs ("Memory error",stderr); exit (2);}
           
        result = fread (buffer, 1, fSize, fp);
        
        if (result != fSize)
           {fputs ("Reading error",stderr); exit (3);}
           
        XorEncrypt(buffer, &key);
        
        fwrite (buffer, 1, fSize, fp);
        
        fclose(fp);
        free(buffer);
       // getch();
        return 0;
    }
    
    int XorEncrypt (char *string, char *key)
    {
        int i, j, mod;
        
        int StringLen = strlen(string); // 20
        int KeyLen = strlen(key); // 6
        
        for (i = 0; i < (StringLen / KeyLen); i++)
        {
            for (j = 0; j < KeyLen; j++)
            {
                string[i*KeyLen + j] ^= key[j];
            }
        }
        
        mod = StringLen % KeyLen;
        
        if (!mod)
        {
             for (i = 0; i < mod; i++)
             {
                 string[-mod + i] ^= key[i];
             }
        }
        
        return 0;
    }

  4. #4
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    string[-mod + i] = string[-mod + i] ^ key[i];

    The above highlighted items can evaluate to a negative number which is probably trashing your key variable making your encryption questionable at best.

  5. #5
    the magic penguim
    Join Date
    Jul 2005
    Posts
    91
    I thought a negative number would cause to select a number from right to left, like:

    char string[] = "abcdef";

    then string[-1] would be f

    But I just tested it and it seems I was wrong... I probably took that assumption from another language like PHP or something =S

    But I beleive that this should fix it:

    Code:
    int XorEncrypt (char *string, char *key)
    {
        int i, j, mod;
        
        int StringLen = strlen(string); // 20
        int KeyLen = strlen(key); // 6
        
        for (i = 0; i < (StringLen / KeyLen); i++)
        {
            for (j = 0; j < KeyLen; j++)
            {
                string[i*KeyLen + j] ^= key[j];
            }
        }
        
        mod = StringLen &#37; KeyLen;
        
        if (mod != 0)
        {
             for (i = 0; i < mod; i++)
             {
                 string[StringLen - mod + i] ^= key[i];
             }
        }
        
        return 0;
    }
    Last edited by lala123; 12-12-2007 at 10:32 AM.

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Code:
    >    XorEncrypt (&string, &key);
    Try:
    Code:
        XorEncrypt (string, key);

  7. #7
    the magic penguim
    Join Date
    Jul 2005
    Posts
    91
    I did, but couldn't notice any difference.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by lala123 View Post
    I did, but couldn't notice any difference.
    There will be no functional difference in the last version.

    And by the way, negative offsets in arrays means[1] "the element before element zero", which of course is invalid for almost all circumstances you can think of. It is sometimes used for memory allocation:
    Code:
    struct allocInfo
    {
        size_t size;
        struct allocInfo *next;
    };
    
    void free(void *p) 
    {
       struct allocInfo *pai;
      
       // find the block just before the memory given by the calling code. 
       pai = &((struct allocInfo *)p)[-1];
       .... 
    }
    [1] Well, technically, I think the C language defines this as "undefined behaviour", meaning anything can happen - mushrooms popping out of the keyboard, computer catches fire, program crashes, or whatever else you can imagine, but for most compilers I've used, it works the way it's described above, and it CAN be used sometimes, as long as the compiler is known to support this trick.

    --
    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
    Join Date
    Jan 2007
    Location
    Euless, TX
    Posts
    144
    Just a point to bring up --- you have your "XorEncrypt" returning an int. My question is why? What do you do with the returned value --- nothing. So why not make it's return type "void". Not an error, but why make it return a value never used again?

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by matsp View Post
    [1] Well, technically, I think the C language defines this as "undefined behaviour", meaning anything can happen - mushrooms popping out of the keyboard, computer catches fire, program crashes, or whatever else you can imagine, but for most compilers I've used, it works the way it's described above, and it CAN be used sometimes, as long as the compiler is known to support this trick.
    Well, since a[b] is defined as *(a+b), then a[x] is valid for any x so long as (a+x) is a valid pointer value. So this is valid:

    Code:
    char string[6] = "Hello";
    char *endstring = string + 5;
    char lastchar = endstring[-1];
    Because endstring == string + 5, endstring[-1] <=> *(endstring - 1) <=> *(string + 5 - 1) <=> *(string + 4) which is valid.

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Hmm. I must be confusing negative offsets with some other stuff that is UB then...

    --
    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
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by matsp View Post
    Hmm. I must be confusing negative offsets with some other stuff that is UB then...

    --
    Mats
    Technically, you may not even possess, let alone dereference, a pointer to unallocated memory (whether it is automatic, global, static, or dynamic memory). The exception is that you can hold a pointer which points exactly one past the end of an allocated block.

    But array accesses devolve to pointer dereferences. If the equivalent pointer dereference would be valid, then the array access is valid too.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by brewbuck View Post
    Technically, you may not even possess, let alone dereference, a pointer to unallocated memory (whether it is automatic, global, static, or dynamic memory). The exception is that you can hold a pointer which points exactly one past the end of an allocated block.

    But array accesses devolve to pointer dereferences. If the equivalent pointer dereference would be valid, then the array access is valid too.
    Oh, sure, accessing memory you don't "own" is definitely UB - but there are certainly cases where one would be able to have a pointer INTO something, and use that pointer to figure out another pointer that is BEFORE that - which is what I've been using a negative offset to do.

    --
    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.

  14. #14
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Quote Originally Posted by matsp View Post
    Oh, sure, accessing memory you don't "own" is definitely UB - but there are certainly cases where one would be able to have a pointer INTO something, and use that pointer to figure out another pointer that is BEFORE that - which is what I've been using a negative offset to do.
    Here's a long thread talking about the fact that merely assigning a pointer to point to something you don't own (other than one-past-the-end) is also UB, although most platforms let you get away with it.

    http://groups.google.com/group/comp....18f6cccd56427d

    Edit: Assigning NULL is also okay (as long as it's not dereferenced, of course).
    Last edited by robatino; 12-13-2007 at 01:55 PM.

  15. #15
    the magic penguim
    Join Date
    Jul 2005
    Posts
    91
    So.... Does anyone know why my code ain't working? The executable runs fine but the file remains unchanged.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. No clue how to make a code to solve problems!
    By ctnzn in forum C Programming
    Replies: 8
    Last Post: 10-16-2008, 02:59 AM
  2. C Pointers Problems
    By mhelal in forum C Programming
    Replies: 8
    Last Post: 01-10-2007, 06:35 AM
  3. String Manipulation problems -_-
    By Astra in forum C Programming
    Replies: 5
    Last Post: 12-13-2006, 05:48 PM
  4. contest problems on my site
    By DavidP in forum Contests Board
    Replies: 4
    Last Post: 01-10-2004, 09:19 PM
  5. DJGPP problems
    By stormswift in forum C Programming
    Replies: 2
    Last Post: 02-26-2002, 04:35 PM