Skip to content

Instantly share code, notes, and snippets.

@doskir
Created January 13, 2012 16:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doskir/1607196 to your computer and use it in GitHub Desktop.
Save doskir/1607196 to your computer and use it in GitHub Desktop.
Image Steganography
private Bitmap EmbeddStringIntoBitmap(Bitmap bmp,string s)
{
//append a NULL terminator
s += '\0';
//for now we only accept 32bit PNG files
if (bmp.PixelFormat != PixelFormat.Format32bppArgb)
throw new Exception();
Bitmap stegBitmap = new Bitmap(bmp);
byte[] stringBytes = Encoding.ASCII.GetBytes(s);
BitArray bits = new BitArray(stringBytes);
if(bits.Length % 3 != 0)
{
BitArray newBits = new BitArray(bits.Length + (3 - bits.Length%3));
for(int i = 0;i < bits.Length;i++)
{
newBits.Set(i, bits[i]);
}
bits = newBits;
}
int bitOffset = 0;
for(int y = 0; y < stegBitmap.Height;y++)
{
if (bitOffset >= bits.Length)
break;
for(int x = 0;x < stegBitmap.Width;x++)
{
if (bitOffset >= bits.Length)
break;
Color pixel = stegBitmap.GetPixel(x, y);
if (pixel.A != 255)
continue;
//set the least significant bit to 0
int red = pixel.R & 254;
//set the least significant bit to one we want
red = red | (bits[bitOffset] ? 1 : 0);
int green = pixel.G & 254;
green = green | (bits[bitOffset+1] ? 1:0);
int blue = pixel.B & 254;
blue = blue | (bits[bitOffset + 2] ? 1 : 0);
bitOffset += 3;
Color newPixel = Color.FromArgb(pixel.A, red, green, blue);
stegBitmap.SetPixel(x, y, newPixel);
}
}
return stegBitmap;
}
private string RetrieveStringFromBitmap(Bitmap bmp)
{
BitArray bits = new BitArray(bmp.Width*bmp.Height*3);
int bitOffset = 0;
for(int y = 0;y < bmp.Height;y++)
{
for(int x = 0;x < bmp.Width;x++)
{
Color pixel = bmp.GetPixel(x, y);
if (pixel.A != 255)
continue;
bool redBit = pixel.R%2==1;
bool greenBit = pixel.G%2 == 1;
bool blueBit = pixel.B%2 == 1;
bits[bitOffset] = redBit;
bits[bitOffset + 1] = greenBit;
bits[bitOffset + 2] = blueBit;
bitOffset += 3;
}
}
StringBuilder sb = new StringBuilder();
for (int offset = 0; offset < bits.Length; )
{
byte b = (byte) (bits[offset] ? 1 : 0);
offset++;
for (; offset%8 != 0; offset++)
{
int temp = 0;
//set the least significant bit to its respective bit in the bitarray
temp |= bits[offset] ? 1 : 0;
//left shift it to the correct position
temp <<= (offset%8);
//OR it with the data we already have to set the correct bit in the assembled byte
b = (byte) (b | temp);
}
char c = (char) b;
//we are checking for a null terminator to easily find the end of the text
if (c == '\0')
break;
sb.Append(c);
}
return sb.ToString();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment