Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.IO;
- using System.Linq;
- using System.Text;
- namespace SteganographyTest
- {
- class Program
- {
- static void Main()
- {
- byte[] hiddenBytes = Util.BitmapToByteArray(Image.FromFile("hidden.png"));
- Encode(hiddenBytes, "innocuous.png", "encoded.png");
- byte[] loadedHiddenBytes = Decode("encoded.png");
- Util.ByteArrayToBitmap(loadedHiddenBytes).Save("decoded.png", ImageFormat.Png);
- CreateMask("innocuous.png", "encoded.png");
- }
- public static void Encode(byte[] hiddenBytes, string inputImageFileName, string outputImageFileName)
- {
- // Loading the data we want to hide to a byte array
- byte[] hiddenLengthBytes = BitConverter.GetBytes(hiddenBytes.Length);
- byte[] hiddenCombinedBytes = Util.Combine(hiddenLengthBytes, hiddenBytes);
- // Loading an innocuous image we want to store the hidden data in to a byte array
- Image innocuousBmp = Image.FromFile(inputImageFileName);
- byte[] rgbComponents = Util.RgbComponentsToBytes(innocuousBmp);
- // Encoding the hidden data into the innocuous image, and storing it to file.
- byte[] encodedRgbComponents = EncodeBytes(hiddenCombinedBytes, rgbComponents);
- Bitmap encodedBmp = Util.ByteArrayToBitmap(encodedRgbComponents, innocuousBmp.Width, innocuousBmp.Height);
- encodedBmp.Save(outputImageFileName, ImageFormat.Png);
- }
- private static byte[] EncodeBytes(byte[] hiddenBytes, byte[] innocuousBytes)
- {
- BitArray hiddenBits = new BitArray(hiddenBytes);
- byte[] encodedBitmapRgbComponents = new byte[innocuousBytes.Length];
- for (int i = 0; i < innocuousBytes.Length; i++)
- {
- if (i < hiddenBits.Length)
- {
- byte evenByte = (byte)(innocuousBytes[i] - innocuousBytes[i] % 2);
- encodedBitmapRgbComponents[i] = (byte)(evenByte + (hiddenBits[i] ? 1 : 0));
- }
- else
- {
- encodedBitmapRgbComponents[i] = innocuousBytes[i];
- }
- }
- return encodedBitmapRgbComponents;
- }
- public static byte[] Decode(string imageFileName)
- {
- // Loading the seemingly innocuous image with hidden data into a byte array
- Bitmap loadedEncodedBmp = new Bitmap(imageFileName);
- byte[] loadedEncodedRgbComponents = Util.RgbComponentsToBytes(loadedEncodedBmp);
- const int bytesInInt = 4;
- byte[] loadedHiddenLengthBytes = DecodeBytes(loadedEncodedRgbComponents, 0, bytesInInt);
- int loadedHiddenLength = BitConverter.ToInt32(loadedHiddenLengthBytes, 0);
- byte[] loadedHiddenBytes = DecodeBytes(loadedEncodedRgbComponents, bytesInInt, loadedHiddenLength);
- return loadedHiddenBytes;
- }
- private static byte[] DecodeBytes(byte[] innocuousLookingData, int byteIndex, int byteCount)
- {
- const int bitsInBytes = 8;
- int bitCount = byteCount * bitsInBytes;
- int bitIndex = byteIndex * bitsInBytes;
- bool[] loadedHiddenBools = new bool[bitCount];
- for (int i = 0; i < bitCount; i++)
- {
- loadedHiddenBools[i] = innocuousLookingData[i + bitIndex] % 2 == 1;
- }
- BitArray loadedHiddenBits = new BitArray(loadedHiddenBools);
- byte[] loadedHiddenBytes = new byte[loadedHiddenBits.Length / bitsInBytes];
- loadedHiddenBits.CopyTo(loadedHiddenBytes, 0);
- return loadedHiddenBytes;
- }
- public static void CreateMask(string inputImageFileName1, string inputImageFileName2)
- {
- Image image1 = Image.FromFile(inputImageFileName1);
- Image image2 = Image.FromFile(inputImageFileName2);
- Bitmap bmp1 = new Bitmap(image1);
- Bitmap bmp2 = new Bitmap(image2);
- Bitmap maskDiff = new Bitmap(bmp1);
- Bitmap maskParity1 = new Bitmap(bmp1);
- Bitmap maskParity2 = new Bitmap(bmp2);
- for (int i = 0; i < maskDiff.Height; i++)
- {
- for (int j = 0; j < maskDiff.Width; j++)
- {
- Color px1 = bmp1.GetPixel(j, i);
- Color px2 = bmp2.GetPixel(j, i);
- int maskDiffIntensity = 255 - Math.Abs(px2.R - px1.R) * 85 - Math.Abs(px2.G - px1.G) * 85 - Math.Abs(px2.B - px1.B) * 85;
- maskDiff.SetPixel(j, i, Color.FromArgb(maskDiffIntensity, maskDiffIntensity, maskDiffIntensity));
- int maskParityIntensity1 = (px1.R % 2) * 85 + (px1.G % 2) * 85 + (px1.B % 2) * 85;
- maskParity1.SetPixel(j, i, Color.FromArgb(maskParityIntensity1, maskParityIntensity1, maskParityIntensity1));
- int maskParityIntensity2 = (px2.R % 2) * 85 + (px2.G % 2) * 85 + (px2.B % 2) * 85;
- maskParity2.SetPixel(j, i, Color.FromArgb(maskParityIntensity2, maskParityIntensity2, maskParityIntensity2));
- }
- }
- maskDiff.Save("maskDiff.png");
- maskParity1.Save("maskParity_" + inputImageFileName1);
- maskParity2.Save("maskParity_" + inputImageFileName2);
- }
- }
- class Util
- {
- public static byte[] BitmapToByteArray(Image img)
- {
- using (MemoryStream ms = new MemoryStream())
- {
- img.Save(ms, ImageFormat.Png);
- return ms.ToArray();
- }
- }
- public static Image ByteArrayToBitmap(byte[] bytes)
- {
- using (MemoryStream ms = new MemoryStream(bytes))
- {
- return Image.FromStream(ms);
- }
- }
- public static byte[] Combine(byte[] left, byte[] right)
- {
- byte[] combined = new byte[left.Length + right.Length];
- Buffer.BlockCopy(left, 0, combined, 0, left.Length);
- Buffer.BlockCopy(right, 0, combined, left.Length, right.Length);
- return combined;
- }
- public static byte[] RgbComponentsToBytes(Image innocuousImg)
- {
- Bitmap innocuousBmp = new Bitmap(innocuousImg);
- int counter = 0;
- byte[] components = new byte[3 * innocuousBmp.Width * innocuousBmp.Height];
- for (int y = 0; y < innocuousBmp.Height; y++)
- {
- for (int x = 0; x < innocuousBmp.Width; x++)
- {
- Color c = innocuousBmp.GetPixel(x, y);
- components[counter++] = c.R;
- components[counter++] = c.G;
- components[counter++] = c.B;
- }
- }
- return components;
- }
- public static Bitmap ByteArrayToBitmap(byte[] rgbComponents, int width, int hight)
- {
- Queue<byte> rgbComponentQueue = new Queue<byte>(rgbComponents);
- Bitmap bitmap = new Bitmap(width, hight);
- for (int y = 0; y < hight; y++)
- {
- for (int x = 0; x < width; x++)
- {
- bitmap.SetPixel(x, y, Color.FromArgb(rgbComponentQueue.Dequeue(), rgbComponentQueue.Dequeue(), rgbComponentQueue.Dequeue()));
- }
- }
- return bitmap;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement