Thread: XOR File Encryption in C

  1. #1
    Registered User
    Join Date
    Mar 2013
    Posts
    11

    Angry XOR File Encryption in C

    My program attempts to encrypt a file using XOR operator. However, when I attempt to encrypt a file, it says "Error in reading file", (a printf function I set up if the program could not read the file, obviously). The problem is that I don't know what's causing this. Instead of encrypting the file, it just deletes all the characters in it, so I put in a fprintf to put place some text into the file. Here is the code:
    Code:
    #include<stdio.h>
    #include<string.h>
    int encryptd(FILE *);
    int main(void)
    {
        FILE *fileptr;
        int recode;
        
        char fname[25];
        
        printf("Enter a file to encrypt:");
        scanf("%s", fname);
        
        fileptr=fopen(fname, "w+");
        
        if(fileptr == NULL){
                   printf("Failed to open file.\n");
                   return -1;
                   }
        else
                   fprintf(fileptr,"text\n");           //place text into file
                   
        
        recode=encryptd(fileptr);
        
        fclose(fileptr);
        
        system("pause");
        return 0;   
        
    }
    int encryptd(FILE *dskfileptr)
    {
        int i;                               //used to index through file buffer
        unsigned long int file_s;            //holds number of bytes in file
        int keylen;                          //holds length of key 
        char *filebuff = NULL;
        
        char key[]="ABCDEF";
        
        keylen=strlen(key);   
        
        fseek(dskfileptr, 0, SEEK_END);      //moves file pointer to end of file
        file_s = ftell(dskfileptr);          //get current file pointer location
                                             //which will be the size of the file
        rewind(dskfileptr);                  //in bytes
        
        filebuff = malloc(file_s);
        
        //read file bytes into RAM filebuff (which is just an array of chars)
        if(fread(filebuff, file_s, 1, dskfileptr) != 1)
        {
                           printf("Error in reading file.\n");
                           return -1;
                           }
        
        for(i=0; i<file_s; i++) //look through each byte of filebuff
        {
                 filebuff[i]=filebuff[i] ^ key[i%keylen];
                 }
        
        rewind(dskfileptr);                   //move file pointer back to the beginning
                                              //of the file
        //write encrypted bytes (in filebuff) back to disk file                                      
        if(fwrite(filebuff, file_s, 1, dskfileptr) != 1)
        {
                            printf("Error in writing encrypted data to file.\n");
                            system("pause");
                            return -1;
                            }
        
        free(filebuff);                       //returning RAM membory back to system
        fclose(dskfileptr);
        
        return 0;
    }
    Attached Files Attached Files

  2. #2
    Registered User
    Join Date
    Nov 2008
    Location
    Phoenix
    Posts
    70
    I think that you're looking for r+ instead of w+ in that first fopen if you are intending to open an existing file. W+ opens a new file, or if it already exists, erases its contents. R+ preserves the contents of an existing file and lets you update it.

  3. #3
    Registered User
    Join Date
    Mar 2013
    Posts
    11
    Yup, I've tried all of them, it still gives me the error.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > fclose(dskfileptr);
    You also close it in main as well.

    Which OS/Compiler are you using?
    Because it seems fine here with Ubuntu/GCC

    If you're on windows, you might need to use "w+b" modes to treat the file as a binary file.
    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.

  5. #5
    Registered User
    Join Date
    Mar 2013
    Posts
    11
    I'm using DEV C++

  6. #6
    Registered User
    Join Date
    Nov 2008
    Location
    Phoenix
    Posts
    70
    I got the program to run properly by changing this:

    Code:
    fileptr=fopen(fname, "w+");
    to this:

    Code:
    fileptr=fopen(fname, "rb+");
    If I remember right, on Windows there's a distinction between text files and binary files, whereas on Linux there isn't? So I think the fread is failing because of this. It is trying to read a single element from the file, where that element size is equal to the entire file size. In text mode, that fails. But in binary mode, it works.

    Plus, I think there's some issue about mixing fscanf and fprintf with fread and fwrite on Windows for files opened in text mode vs files opened in binary mode? Beyond that, I don't know the nitty gritty details.

  7. #7
    Registered User
    Join Date
    Mar 2013
    Posts
    11
    Salem, in main(void), its fclose(fileptr), in the encrypted function its fclose(dskfileptr). I've changed the fopen(fname, "w+"); to fopen(fname, "rb+") as suggested, and it works. Thank you.

  8. #8
    Registered User ledow's Avatar
    Join Date
    Dec 2011
    Posts
    435
    Quote Originally Posted by andrey.117 View Post
    Salem, in main(void), its fclose(fileptr), in the encrypted function its fclose(dskfileptr).
    That's the problem. Because you pass fileptr to the function which becomes known by another name (dskfileptr). So you effectively close the same file twice, just using two different pointers to the same file handle. That's why Salem said it.

    P.S. if you looked at the return of the fclose functions you have, I bet that the one in main returns an error (EOF) because it's already closed that file once.

    It won't affect anything important, but it's sloppiness that can lead to worse problems if you go on to extend the program further.
    Last edited by ledow; 03-20-2013 at 07:51 AM.

    - Compiler warnings are like "Bridge Out Ahead" warnings. DON'T just ignore them.
    - A compiler error is something SO stupid that the compiler genuinely can't carry on with its job. A compiler warning is the compiler saying "Well, that's bloody stupid but if you WANT to ignore me..." and carrying on.
    - The best debugging tool in the world is a bunch of printf()'s for everything important around the bits you think might be wrong.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 03-08-2012, 05:37 PM
  2. File Encryption
    By Jack Walters in forum C++ Programming
    Replies: 17
    Last Post: 11-13-2007, 10:47 AM
  3. file encryption?
    By elfjuice in forum C++ Programming
    Replies: 5
    Last Post: 07-02-2002, 07:39 PM
  4. File Encryption...
    By |<4D4\/3r in forum C++ Programming
    Replies: 3
    Last Post: 04-02-2002, 03:30 AM
  5. File Encryption in C
    By a_learner in forum C Programming
    Replies: 2
    Last Post: 10-18-2001, 03:19 PM

Tags for this Thread