Skip to content

Instantly share code, notes, and snippets.

@ruarai
Created January 8, 2015 03:21
Show Gist options
  • Select an option

  • Save ruarai/f6d127f4df7c66b7bc56 to your computer and use it in GitHub Desktop.

Select an option

Save ruarai/f6d127f4df7c66b7bc56 to your computer and use it in GitHub Desktop.
Steganography of big text files.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FearImageSteganography
{
class Program
{
static void Main(string[] args)
{
//File.WriteAllText("out.txt",ReadImage((Bitmap)Image.FromFile("test1.png")));
string text = File.ReadAllText("in.txt");
Stopwatch s = new Stopwatch();
s.Start();
var i = MakeImage(text);
Console.WriteLine("Optimised time :{0}ms", s.ElapsedMilliseconds);
i.Save("testout.png");
s.Restart();
CreateImage(text,3638);
Console.WriteLine("Old time :{0}ms", s.ElapsedMilliseconds);
Console.ReadKey();
}
static Image MakeImage(string text)
{
int[] squareInts = new int[4096];
for (int i = 0; i < squareInts.Length; i++)
{
squareInts[i] = (int)Math.Pow(i, 2);
}
int numPixels = text.Length / bytesPerPixel;
int width = 0;
int realPixels = 0;
foreach (int i in squareInts)
{
if (numPixels <= i)
{
width = Array.IndexOf(squareInts, i);
realPixels = i;
break;
}
}
Console.WriteLine("Making an image of width {0} with {1} total pixels and {2} data pixels.",width,realPixels,numPixels);
int numMissing = (realPixels - numPixels) * bytesPerPixel;
byte[] missingFiller = new byte[numMissing];
byte[] byteArray = Encoding.UTF8.GetBytes(text);
byte[] outArray = new byte[byteArray.Length + missingFiller.Length];
byteArray.CopyTo(outArray, 0);
missingFiller.CopyTo(outArray, byteArray.Length);
Bitmap buffer = new Bitmap(width, width);
int index = 0;
for (int x = 0; x < width; x++)
{
for (int y = 0; y < width; y++)
{
byte r = outArray[index];
index++;
byte g = outArray[index];
index++;
byte b = outArray[index];
index++;
if (bytesPerPixel == 4)
{
byte a = outArray[index];
index++;
buffer.SetPixel(x, y, Color.FromArgb(a, r, g, b));
}
else
{
buffer.SetPixel(x, y, Color.FromArgb(r, g, b));
}
}
}
Console.WriteLine("{0} bytes.", byteArray.Length);
return buffer;
}
private const int bytesPerPixel = 4;
static string ReadImage(Bitmap b)
{
byte[] byteArray = new byte[b.Width * b.Height * bytesPerPixel];
int i = 0;
for (int x = 0; x < b.Width; x++)
{
for (int y = 0; y < b.Height; y++)
{
if (bytesPerPixel == 4)
{
byteArray[i] = b.GetPixel(x, y).A;
i++;
}
byteArray[i] = b.GetPixel(x, y).R;
i++;
byteArray[i] = b.GetPixel(x, y).G;
i++;
byteArray[i] = b.GetPixel(x, y).B;
i++;
}
}
return Encoding.UTF8.GetString(byteArray);
}
private static Bitmap CreateImage(String inputText,int width)
{
Queue<Byte> queue = new Queue<Byte>(Encoding.UTF8.GetBytes(inputText));
var image = new Bitmap(width, width);
for (int x = 0; x < width; x++)
{
for (int y = 0; y < width; y++)
{
if (queue.Count > 0)
{
List<Byte> colorValues = new List<Byte>(4);
for (int c = 0; c < 3; c++)
{
if (queue.Count > 0)
{
colorValues.Add(queue.Dequeue());
}
else
{
colorValues.Add(0);
}
}
var pixel = Color.FromArgb(255, colorValues[0], colorValues[1], colorValues[2]);
image.SetPixel(x, y, pixel);
}
else
{
image.SetPixel(x, y, Color.FromArgb(0, 0, 0, 0));
}
}
}
return image;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment