Skip to main content
gamedev.net
🔒 Locked

Encrypting files

Started by jman2050 10 replies 950+ views
Original Post
jman2050
jman2050
HEllo, I'm trying to figure out a way to make this encryption scheme work. Basically, I am writing to a file, and then afterwards trying to scramble it using my own key. Here's a code snippet:
fseek(file, 0, SEEK_SET);

        for(n=0; !feof(file); n++)
        {
            buffer = getc(file);
            fseek(file, -1, SEEK_CUR);
            buffer >> scramble[n%50];
            putc(buffer, file);
        }
 
scramble is a 50-char key string that's supposed to be used whe shifting the character received from getc. The second fseek is to move the cursor bak once getc is done so the file can be overwritten. The file is open in "w+b" mode. I try this code but all it does is take the second character and repeat it over and over and over again in the file, overwriting what was already there. Interestingly, the first character is intact. Can someone tell me what is wrong? [edited by - jman2050 on January 9, 2003 5:20:57 PM]
daerid
daerid
fix your code tag
daerid@gmail.com
CWizard
CWizard
Make [/CODE] to [/code] NOW!

I just don''t get this line. A typo?
buffer >> scramble[n%50];

Do you mean:

buffer += scramble[n % 50];
// or...
buffer >>= scramble[n % 50];
// or something else?


jman2050
jman2050
I typed what I typed. That''s the right bitwise shift operator. Just to make sure, I tried different expressions. It didn''t help. I really wish someone could help me.
CWizard
CWizard
buffer >> scramble[n%50];
won''t do anything, unless you assign the result to anything. Either by:
buffer = buffer >> scramble[n % 50];/
or:
buffer >>= scramble[n % 50];

Both getc() and putc() works with ints, but your shift wont work well with that. Unless buffer is a char, you must do something like:
buffer = (char)buffer >> scramble[n % 50];

It would be helpful if we could see the entire code.


CWizard
CWizard
A few problems with your code:
* You cannot shift like that. The C shift operator is not cyclic, ie. what pops out on the right won''t pop in on the left.
* The seeking mess up the file somehow (noticed it by my own experiments). It clears the EOF flag, and somehow truncates the file (why you get the same character over and over again). You should write to a temporary file.

Some code I wrote, but the file i/o doesn''t work. It would if you wrote to separate files:

  
bool encrypt(char *filename, char *key, int key_length)
{
FILE *file;
if(!(file = fopen(filename, "rb+"))) return false;

char c;
for(int fp = 0, kp = 0; !feof(file); fp++, kp += (kp < key_length) ? 1 : -key_length) {
c = (char)fgetc(file);
c += key[kp];
fseek(file, -1, SEEK_CUR);
fputc((int)c, file);
}
return true;
}



jman2050
jman2050
Interesting. I got it to work to a degree. The new code is here:


fseek(file, 0, SEEK_SET);

for(n=0; n {
buffer = getc(file);
fseek(file, n, SEEK_SET);
buffer = buffer >> scramble[n%50];
putc(buffer, file);
}


However, when it does this, it only encrypts the first four bytes of the text file. I''m suspecting that sizeof returns the siz of the structure, not the actual file. And since I''m writing to the file EOF isn''t working for me. Is there any way to find the actual physical size of the file opened?
CWizard
CWizard
Still, you cannot shift like you do. Unless you implement your own cyclic shift function or use assembly, you loose information. It works like this:
You read the first byte from file, say "A" == 0x41 == %01000001.
The current scrambler byte is 7, and when you shift by it, you''ll end up with this:

0x41 == %01000001 | --------
0x41 >> 0x07 == %00000000 | 10000010

The part right to the bar end up in the mysterious bit bucket, which nothing ever comes back from. So you have nothing left, and cannot get it back.

sizeof() does, of course, not give the size of the file. sizeof(file) would give you 4. You can get the size of an opened file this way:
fseek(file, 0, SEEK_END);
file_size = ftell(file);

Again, you shouldn''t read and write from the same file. It is, of course, possible, but it is harder to do. Start of implementing the function using a temporary file, and when it works (ie. data == decrypt(encrypt(data))), then do it on the same file. It will save you trouble by doing so.


HyprLogik
HyprLogik
Actually, you _can_ write

buffer >> scramble[...];

without having to include an assignment operator.
The problem lies with the use of fseek(). As far as I can tell, you're never traversing the file past the first character, which is why the remaining characters are never looked at. Add in a line that iterates through the file. Use fseek() as before, except this time the offset argument should be incremented each time around the loop. I don't see why you would need to move the cursor back each time around. Let me know if this makes any sense

[edited by - HyprLogik on January 9, 2003 10:17:47 PM]
|-|A[k3R$Z R //|-|AT |V|Ak3 t|-|3 //0R|D g0 R0||||D!!
NickB
NickB
yes, sizeof is returning the size of the file pointer you are using.

to get the file size you could do this:

fseek(file, 0, SEEK_END);
int fSize = ftell(file);
fseek(file, 0, SEEK_SET);

for(n=0; n ...
}
Dean Harding
Dean Harding
quote:
Original post by HyprLogik
Actually, you _can_ write

buffer >> scramble[...];



No, the >> operator has no effect on either of it''s operands.

Writing a cyclic shift right is not that hard, something like the following will do:

inline int rotr( int value, int amount )
{
    return (value >> amount) | (value << (sizeof(int) - amount));
}


Another operation you can use is the infamous XOR operation which would be a bit faster, since it''s only one XOR, not two shifts and an OR.

If I had my way, I''d have all of you shot!


codeka.com - Just click it.

jman2050
jman2050
The reason I did that with fseek is because after getc is called, the file pointer is moved to the next byte. I''m trying to overwrite the file, so I tried to use that fseek statement to move the pointer back so it can overwrite the last character it got. Of course, in practice, you will always find a better way:


fseek(file, n, SEEK_SET);


where n is the variable I am incrementing which each iteration of the loop. This way, the file pointer will increment only once in each iteration before it writes, as well as set up for getc.

I found a working method to actually encrypt the file, but I''m trying to find a good encryption scheme. I imagine XOR would work for the moment but in the future I would like something a bit more secure. Thanks for all your help though.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.