websitesvalues
websitesvalues

Reputation: 137

How to use XOR to Encrypt a music file

I want to encrypt and decrypt 10000 bytes of a music file. I used the code :

if(file!=NULL && g!= NULL)  
{
    while(!feof(file))
    {
        count++;
        char aByte;
        fread(&aByte, sizeof(char), 1, file);
        if (count <= 10000)
        {
            if (count % 2 == 0)
            {
                if ((aByte ^ 'A') != EOF) aByte = aByte ^ 'A';
            }
            else 
            {
                if ((aByte ^ 'B') != EOF) aByte = aByte ^ 'B';
            }
        }
        fwrite(&aByte, sizeof(char), 1, g);
    }
}   
fclose(file);

But the code does not work. Please help!!!

Upvotes: 1

Views: 454

Answers (2)

Lou Franco
Lou Franco

Reputation: 89192

Test your file handling by removing the "encryption". Take out these lines

        if (count % 2 == 0)
        {
            if ((aByte ^ 'A') != EOF) aByte = aByte ^ 'A';
        }
        else 
        {
            if ((aByte ^ 'B') != EOF) aByte = aByte ^ 'B';
        }

Is your file the exact same? I think it will not be. Here are some reasons

  1. The file is longer than 10,000 bytes -- you close file at the end, so I assume that those bytes are lost
  2. The file is less than 10,000 bytes -- you don't check for EOF property, so it looks like an extra byte will be written
  3. count is not initialized in this code -- if it's odd on one run and even on another, it wont' match. Also, it's just going to copy a random number of bytes depending on what count is. Perhaps it's initialized elsewhere.
  4. You don't close g, so you can't be sure it was flushed (fwrite can buffer writes)

UPDATE: EOF is not a byte that you can find in a file, it's a special return value used by some FILE API functions (not fread).

The function getchar() is defined like this:

  int getchar();

It either returns EOF or an int that is within the range of char. If it's EOF, then that means that you are at the end of the file. If not, you may safely cast the return to a char. The only stipulation on EOF is that it isn't a valid char. getchar() returns an int because it can return any char (256 choices) + EOF for a total of 257 choices which can't be represented in a char.

If you look at fread(), you will see that it doesn't have anything to do with chars. It takes a buffer, and record size, and a record count and returns the number of bytes read. You happen to be passing in sizeof(char) and 1 to get a char. It couldn't possibly store EOF in that char because EOF is not a valid char, it's an int and won't fit. It doesn't use the same conventions as getchar(). If it encounters EOF, it returns a number less than the total number of bytes requested. In your case, that's 0. If fread() returns 0, check feof() and ferror() to find out if you got to the end-of-file or got an error (both cause fread to return less than the number requested).

Upvotes: 1

David
David

Reputation: 2871

You shouldn't do the XOR when you're checking for EOF (which, by the way, fread indicates in its return value rather than in the value it writes to your buffer); only when you're preparing the byte to be written to the file.

Also, you'll need a much longer key if you want to encrypt it properly — and the key must be unknown to anyone who isn't supposed to be able to decrypt it.

Upvotes: 2

Related Questions