views:

100

answers:

4
public void EncryptFile()
    {            
        OpenFileDialog dialog = new OpenFileDialog();
        dialog.Filter = "JPEG Files (*.jpeg)|*.jpeg|PNG Files (*.png)|*.png|All files (*.*)|*.*";
        dialog.InitialDirectory = @"C:\";
        dialog.Title = "Please select an image file to encrypt.";
        if (dialog.ShowDialog() == DialogResult.OK)
        {
            byte[] ImageBytes = File.ReadAllBytes(dialog.FileName);

            foreach (byte X in ImageBytes)
            {
                //How can I take byte "X" and add a numerical value to it?
            }
        }             
    }

So, I'm trying to encrypt an image file by just converting it to byte[] array and then adding a numerical value to each byte.

How can I add a numerical value to a byte?

+2  A: 

You just add it. The problem is that you can't modify the value in your foreach loop there. You actually want a for loop:

for(int k = 0; k < ImagesBytes.Length; k++){
   ImageBytes[k] = (byte) (ImageBytes[k] + 5); // needs a cast
}
Noon Silk
itowlson: Actually, It'll just overflow happily (no crashing).
Noon Silk
Would you mind sharing why I can't use the foreach iterator?
Sergio Tapia
Papuccino1: zneak else explained it below, but basically, you can't assign to foreach variables (it's specifically disallowed). Regardless of that, though, you generally can't modify the object you're looping over, in a foreach statement. If you want to modify (i.e. set an element of the array) the typical for loop (or some variant) is appropriate.
Noon Silk
Hot diggity, so it will. Sorry about that!
itowlson
A: 

byte is a value type, which means it's always copied when it's returned. Consequently, you can only add a value to the local byte value inside your foreach, pretty much like changing the value of a byte argument inside a function won't change the value outside the function (unless, of course, you used the ref keyword).

You can't use a foreach for this task. Use a regular for loop:

for(int i = 0; i < ImageBytes.Length; i++)
    ImageBytes[i] += MyNumericValue;
zneak
I'd also like to say that adding a value to a byte in order to encrypt is more obfuscation than encryption.
zneak
A: 

You need to use modulo (specifically modulo 256) addition, so that the operation is reversible. Alternatively you could use a bitwise operation, XOR is a common choice.

Modulo 256 operation is simple to implement for bytes, you just need to cast the result, as in:

ImageBytes[k] = (unsigned byte) ((unsigned byte) ImageBytes[k] + x)

Beware however that such "encryption" is rather weak. A way to improve the strength of such encryption is to add a distinct value for each byte, for example by taking the added value in a circular buffer (i.e. with a sequence which eventually repeats itself). A better way, still may use the values readily decoded as part of the operands.

mjv
Thank you very much for the tips. I'll be sure to implement something like this when I finish Step 1. Cut a hole in the box. GOTO Step 2.
Sergio Tapia
A: 

Question: Why not just use one of the built in crypto streams in .NET?

If you don't want to do that, assuming that you are going to want to use the image in some way after you obscure the bits of it, I would look at doing a custom stream class and just modify the bytes are the come in.

There is a great end to end walk through here Custom Transform Streams (and the rotate stream would be a better faster way to solve your problem of obscuring the image file). This also gets rid of the overflow issues with adding to a byte.

Brian ONeil