예제 #1
0
        protected override double Calculation(LockBitmap originalBmp, LockBitmap steganoBmp)
        {
            Color orig;
            Color steg;
            var originalDiffernce = 0.0;
            var totalDifference = 0.0;
            for (var y = 0; y < originalBmp.Height; y++)
            {
                for (var x = 0; x < originalBmp.Width; x++)
                {
                    orig = originalBmp.GetPixel(x, y);
                    steg = steganoBmp.GetPixel(x, y);

                    originalDiffernce += Math.Pow(Math.Abs(orig.R) +
                                                  Math.Abs(orig.G) +
                                                  Math.Abs(orig.B), 2);
                    totalDifference += Math.Pow(Math.Abs(orig.R
                                                         - steg.R)
                                                + Math.Abs(orig.G
                                                           - steg.G)
                                                + Math.Abs(orig.B
                                                           - steg.B), 2);
                }
            }
            return originalDiffernce/totalDifference;
        }
        protected override double Calculation(LockBitmap originalBmp, LockBitmap steganoBmp)
        {
            Color orig;
            Color steg;
            var size = originalBmp.Height*originalBmp.Width;
            var totalDifference = 0.0;
            var maxDifference = 0.0;
            double currentDifference;
            for (var y = 0; y < originalBmp.Height; y++)
            {
                for (var x = 0; x < originalBmp.Width; x++)
                {
                    orig = originalBmp.GetPixel(x, y);
                    steg = steganoBmp.GetPixel(x, y);

                    currentDifference = Math.Pow(Math.Abs(orig.R) +
                                                 Math.Abs(orig.G) +
                                                 Math.Abs(orig.B), 2);
                    if (currentDifference >= maxDifference)
                        maxDifference = currentDifference;
                    totalDifference += Math.Pow(Math.Abs(orig.R
                                                         - steg.R)
                                                + Math.Abs(orig.G
                                                           - steg.G)
                                                + Math.Abs(orig.B
                                                           - steg.B), 2);
                }
            }
            return size*maxDifference/totalDifference;
        }
예제 #3
0
 public static void ChangeColor(Bitmap src, Color color, IEnumerable<Pixel> changedPixels)
 {
     var lockBitmap = new LockBitmap(src);
     lockBitmap.LockBits();
     foreach (var changedPixel in changedPixels)
     {
         lockBitmap.SetPixel(changedPixel.X, changedPixel.Y, color);
     }
     lockBitmap.UnlockBits();
 }
예제 #4
0
        /**
        * Outputs a laplace graph in csv format.
        *
        * The CSV file will be comma separated, and is
        * written to the specified place on disk.
        *
        * @param image The image to create the laplace graph of.
        * @return A string representation of the laplace graph in
        * the format of CSV.
        */
        public static string GetCSVGraph(LockBitmap image)
        {
            var sb = new StringBuilder();
            sb.Append("\"Frequency\",\"Laplace Value\"\n");
            var graph = GetGraph(image);
            for (var i = 0; i < graph.Length; i++)
            {
                sb.Append(graph[i][1] + "," + graph[i][0] + "\n");
            }

            sb.Append("\n\n");
            return sb.ToString();
        }
예제 #5
0
 protected Filter(LockBitmap image, int startbits, int endbits)
 {
     if (image == null)
     {
         throw new ArgumentNullException(nameof(image));
     }
     Image = image;
     StartRange = startbits;
     EndRange = endbits;
     ByteMask = GetByteMask();
     if (!image.IsLocked)
     {
         image.LockBits();
     }
 }
 protected override double Calculation(LockBitmap originalBmp, LockBitmap steganoBmp)
 {
     var size = originalBmp.Height*originalBmp.Width;
     Color orig;
     Color steg;
     var difference = 0.0;
     for (var y = 0; y < originalBmp.Height; y++)
     {
         for (var x = 0; x < originalBmp.Width; x++)
         {
             orig = originalBmp.GetPixel(x, y);
             steg = steganoBmp.GetPixel(x, y);
             difference += Math.Abs(orig.R - steg.R) + Math.Abs(orig.G - steg.G) +
                           Math.Abs(orig.B - steg.B);
         }
     }
     return difference/size;
 }
        protected override double Calculation(LockBitmap originalBmp, LockBitmap steganoBmp)
        {
            var origFiltered = new Laplace(originalBmp, 0, 8);
            var stegoFiltered = new Laplace(steganoBmp, 0, 8);
            var originalDiff = 0.0;
            var totalDiff = 0.0;

            for (var y = 0; y < originalBmp.Height; y++)
            {
                for (var x = 0; x < originalBmp.Width; x++)
                {
                    //TODO Shouldnt that be the other direction? First TOTAL and second ORIGINAL?
                    originalDiff += Math.Pow(origFiltered.GetValue(x, y) - stegoFiltered.GetValue(x, y), 2);
                    totalDiff += Math.Pow(origFiltered.GetValue(x, y), 2);
                }
            }

            return originalDiff/totalDiff;
        }
예제 #8
0
        public static Bitmap ChangeColor(Bitmap src, Color color)
        {
            var result = new Bitmap(src);
            var lockBitmap = new LockBitmap(result);
            lockBitmap.LockBits();

            var compareClr = Color.FromArgb(255, 255, 255, 255);
            for (var y = 0; y < lockBitmap.Height; y++)
            {
                for (var x = 0; x < lockBitmap.Width; x++)
                {
                    if (lockBitmap.GetPixel(x, y) == compareClr)
                    {
                        lockBitmap.SetPixel(x, y, color);
                    }
                }
            }
            lockBitmap.UnlockBits();
            return result;
        }
예제 #9
0
        /*
         * A small main method that will print out the message length
         * in percent of pixels.
         */
        public static void Main(string[] args)
        {
            if (args.Length != 1)
            {
                Console.WriteLine("Usage: invisibleinktoolkit.benchmark.SamplePairs <imagefilename>");
                Environment.Exit(1);
            }
            try
            {
                Console.WriteLine("\nSample Pairs Results");
                Console.WriteLine("--------------------");
                var sp = new SamplePairs();
                using (var bitmap = new Bitmap(args[0]))
                {
                    var image = new LockBitmap(bitmap);
                    image.LockBits();

                    double average = 0;
                    var results = sp.DoAnalysis(image, ANALYSIS_COLOUR_RED);
                    Console.WriteLine("Result from red: " + results);
                    average += results;
                    results = sp.DoAnalysis(image, ANALYSIS_COLOUR_GREEN);
                    Console.WriteLine("Result from green: " + results);
                    average += results;
                    results = sp.DoAnalysis(image, ANALYSIS_COLOUR_BLUE);
                    Console.WriteLine("Result from blue: " + results);
                    average += results;
                    average = average/3;
                    Console.WriteLine("Average result: " + average);
                    Console.WriteLine();

                    image.UnlockBits();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("ERROR: Cannot process that image type, please try another image.");
                Console.WriteLine(e.StackTrace);
            }
        }
예제 #10
0
        public double Calculate(Bitmap originalBmp, Bitmap steganoBmp)
        {
            if (originalBmp == null)
            {
                throw new ArgumentNullException(nameof(originalBmp));
            }

            if (originalBmp == null)
            {
                throw new ArgumentNullException(nameof(steganoBmp));
            }

            var original = new LockBitmap(originalBmp);
            original.LockBits();
            var stegano = new LockBitmap(steganoBmp);
            stegano.LockBits();
            var result = Calculation(original, stegano);

            original.UnlockBits();
            stegano.UnlockBits();
            return result;
        }
예제 #11
0
 public Prewitt(LockBitmap image, int startbits, int endbits)
     : base(image, startbits, endbits)
 {
 }
예제 #12
0
 protected abstract double Calculation(LockBitmap originalBmp, LockBitmap steganoBmp);
예제 #13
0
        /*
         * Does an RS analysis of a given image.
         * <P>
         * The analysis data returned is specified by name in
         * the getResultNames() method.
         *
         * @param image The image to analyse.
         * @param colour The colour to analyse.
         * @param overlap Whether the blocks should overlap or not.
         * @return The analysis information.
         */
        public double[] DoAnalysis(LockBitmap image, int color, bool overlap)
        {
            int startx = 0, starty = 0;
            var block = new Color[mM*mN];
            double numregular = 0, numsingular = 0;
            double numnegreg = 0, numnegsing = 0;
            double numunusable = 0, numnegunusable = 0;
            double variationB = 0, variationP = 0, variationN = 0;
            while (startx < image.Width && starty < image.Height)
            {
                //this is done once for each mask...
                for (var m = 0; m < 2; m++)
                {
                    //get the block of data
                    var k = 0;
                    for (var i = 0; i < mN; i++)
                    {
                        for (var j = 0; j < mM; j++)
                        {
                            block[k] = image.GetPixel(startx + j, starty + i);
                            k++;
                        }
                    }

                    // get the variation the block
                    variationB = GetVariation(block, color);

                    //now flip according to the mask
                    block = FlipBlock(block, mMask[m]);
                    variationP = GetVariation(block, color);
                    //flip it back
                    block = FlipBlock(block, mMask[m]);

                    //negative mask
                    mMask[m] = InvertMask(mMask[m]);
                    variationN = GetNegativeVariation(block, color, mMask[m]);
                    mMask[m] = InvertMask(mMask[m]);

                    //now we need to work out which group each belongs to
                    //positive groupings
                    if (variationP > variationB)
                    {
                        numregular++;
                    }
                    if (variationP < variationB)
                    {
                        numsingular++;
                    }
                    if (variationP == variationB)
                    {
                        numunusable++;
                    }

                    //negative mask groupings
                    if (variationN > variationB)
                    {
                        numnegreg++;
                    }
                    if (variationN < variationB)
                    {
                        numnegsing++;
                    }
                    if (variationN == variationB)
                    {
                        numnegunusable++;
                    }

                    //now we keep going...
                }
                //get the next position
                if (overlap)
                    startx += 1;
                else
                    startx += mM;

                if (startx >= image.Width - 1)
                {
                    startx = 0;
                    if (overlap)
                    {
                        starty += 1;
                    }
                    else
                    {
                        starty += mN;
                    }
                }
                if (starty >= image.Height - 1)
                {
                    break;
                }
            }
            //get all the details needed to derive x...
            var totalgroups = numregular + numsingular + numunusable;
            var allpixels = GetAllPixelFlips(image, color, overlap);
            var x = GetX(numregular, numnegreg, allpixels[0], allpixels[2],
                numsingular, numnegsing, allpixels[1], allpixels[3]);

            //calculate the estimated percent of flipped pixels and message length
            double epf, ml;
            if (2*(x - 1) == 0)
                epf = 0;
            else
                epf = Math.Abs(x/(2*(x - 1)));

            if (x - 0.5 == 0)
                ml = 0;
            else
                ml = Math.Abs(x/(x - 0.5));

            //now we have the number of regular and singular groups...
            var results = new double[28];

            //save them all...

            //these results
            results[0] = numregular;
            results[1] = numsingular;
            results[2] = numnegreg;
            results[3] = numnegsing;
            results[4] = Math.Abs(numregular - numnegreg);
            results[5] = Math.Abs(numsingular - numnegsing);
            results[6] = numregular/totalgroups*100;
            results[7] = numsingular/totalgroups*100;
            results[8] = numnegreg/totalgroups*100;
            results[9] = numnegsing/totalgroups*100;
            results[10] = results[4]/totalgroups*100;
            results[11] = results[5]/totalgroups*100;

            //all pixel results
            results[12] = allpixels[0];
            results[13] = allpixels[1];
            results[14] = allpixels[2];
            results[15] = allpixels[3];
            results[16] = Math.Abs(allpixels[0] - allpixels[1]);
            results[17] = Math.Abs(allpixels[2] - allpixels[3]);
            results[18] = allpixels[0]/totalgroups*100;
            results[19] = allpixels[1]/totalgroups*100;
            results[20] = allpixels[2]/totalgroups*100;
            results[21] = allpixels[3]/totalgroups*100;
            results[22] = results[16]/totalgroups*100;
            results[23] = results[17]/totalgroups*100;

            //overall results
            results[24] = totalgroups;
            results[25] = epf;
            results[26] = ml;
            results[27] = image.Width*image.Height*3*ml/8;

            return results;
        }
 protected LockBitmap LockBitmap(string src)
 {
     var lockBitmap = new LockBitmap(new Bitmap(src));
     lockBitmap.LockBits();
     return lockBitmap;
 }
예제 #15
0
        /**
         * Gets the RS analysis results for flipping performed on all
         * pixels.
         *
         * @param image The image to analyse.
         * @param colour The colour to analyse.
         * @param overlap Whether the blocks should overlap.
         * @return The analysis information for all flipped pixels.
         */
        private double[] GetAllPixelFlips(LockBitmap image, int colour, bool overlap)
        {
            //setup the mask for everything...
            var allmask = new int[mM*mN];
            for (var i = 0; i < allmask.Length; i++)
            {
                allmask[i] = 1;
            }

            //now do the same as the doAnalysis() method

            int startx = 0, starty = 0;
            var block = new Color[mM*mN];
            double numregular = 0, numsingular = 0;
            double numnegreg = 0, numnegsing = 0;
            double numunusable = 0, numnegunusable = 0;
            double variationB, variationP, variationN;

            while (startx < image.Width && starty < image.Height)
            {
                //done once for each mask
                for (var m = 0; m < 2; m++)
                {
                    //get the block of data
                    var k = 0;
                    for (var i = 0; i < mN; i++)
                    {
                        for (var j = 0; j < mM; j++)
                        {
                            block[k] = image.GetPixel(startx + j, starty + i);
                            k++;
                        }
                    }

                    //flip all the pixels in the block (NOTE: THIS IS WHAT'S DIFFERENT
                    //TO THE OTHER doAnalysis() METHOD)
                    block = FlipBlock(block, allmask);

                    //get the variation the block
                    variationB = GetVariation(block, colour);

                    //now flip according to the mask
                    block = FlipBlock(block, mMask[m]);
                    variationP = GetVariation(block, colour);
                    //flip it back
                    block = FlipBlock(block, mMask[m]);

                    //negative mask
                    mMask[m] = InvertMask(mMask[m]);
                    variationN = GetNegativeVariation(block, colour, mMask[m]);
                    mMask[m] = InvertMask(mMask[m]);

                    //now we need to work out which group each belongs to

                    //positive groupings
                    if (variationP > variationB)
                        numregular++;
                    if (variationP < variationB)
                        numsingular++;
                    if (variationP == variationB)
                        numunusable++;

                    //negative mask groupings
                    if (variationN > variationB)
                        numnegreg++;
                    if (variationN < variationB)
                        numnegsing++;
                    if (variationN == variationB)
                        numnegunusable++;

                    //now we keep going...
                }
                //get the next position
                if (overlap)
                    startx += 1;
                else
                    startx += mM;

                if (startx >= image.Width - 1)
                {
                    startx = 0;
                    if (overlap)
                        starty += 1;
                    else
                        starty += mN;
                }
                if (starty >= image.Height - 1)
                    break;
            }
            //save all the results (same order as before)
            var results = new double[4];

            results[0] = numregular;
            results[1] = numsingular;
            results[2] = numnegreg;
            results[3] = numnegsing;

            return results;
        }
예제 #16
0
 public Sobel(LockBitmap image, int startbits, int endbits)
     : base(image, startbits, endbits)
 {
 }
예제 #17
0
        //FUNCTIONS
        /**
         * Runs all the steganalysis.
         *
         * @param stego The stego image to test.
         * @return All the results as text.
         * @throws IllegalArgumentException If the stego image is null.
         * @throws Exception If it has problems reading the images.
         */
        public string Run(Bitmap stego)
        {
            using (stego)
            {
                var image = new LockBitmap(stego);
                image.LockBits();
                var results = new StringBuilder("Results of steganalysis\n"
                                                + "==========================\n\n");

                string colour;
                double averageresults = 0, averagelength = 0;

                //RS Analysis
                if (mRunRsAnalysis)
                {
                    results.Append("RS ANALYSIS\n" + "============\n\n");
                    results.Append("RS Analysis (Non-overlapping groups)\n");
                    for (var j = 0; j < 3; j++)
                    {
                        var rsa = new RsAnalysis(2, 2);
                        var testresults =
                            rsa.DoAnalysis(image, j, false);

                        //get the right colour
                        if (j == 0)
                        {
                            colour = "red";
                        }
                        else if (j == 1)
                        {
                            colour = "green";
                        }
                        else
                        {
                            colour = "blue";
                        }

                        //Append the results
                        results.Append("Percentage in " + colour + ": ");

                        //Round and Append results
                        results.Append(Round(testresults[26]*100, 5) + "\n");

                        //and the approximate length (in bytes)
                        results.Append("Approximate length (in bytes) from " + colour + ": "
                                       + Round(testresults[27], 5) + "\n");

                        averageresults += testresults[26];
                        averagelength += testresults[27];
                    }

                    //now do again for overlapping groups
                    results.Append("\nRS Analysis (Overlapping groups)\n");
                    for (var j = 0; j < 3; j++)
                    {
                        var rsa = new RsAnalysis(2, 2);
                        var testresults =
                            rsa.DoAnalysis(image, j, true);

                        //get the right colour
                        if (j == 0)
                        {
                            colour = "red";
                        }
                        else if (j == 1)
                        {
                            colour = "green";
                        }
                        else
                        {
                            colour = "blue";
                        }

                        //Append the results
                        results.Append("Percentage in " + colour + ": ");

                        //Round and Append results
                        results.Append(Round(testresults[26]*100, 5) + "\n");

                        //and the approximate length (in bytes)
                        results.Append("Approximate length (in bytes) from " + colour + ": "
                                       + Round(testresults[27], 5) + "\n");

                        averageresults += testresults[26];
                        averagelength += testresults[27];
                    }

                    results.Append("\nAverage across all groups/colours: " +
                                   Round(averageresults/6*100, 5));
                    results.Append("\nAverage approximate length across all groups/colours: " +
                                   Round(averagelength/6, 5));
                    results.Append("\n\n\n");
                }

                //Sample Pairs
                averageresults = 0;
                averagelength = 0;
                if (mRunSamplePairs)
                {
                    results.Append("SAMPLE PAIRS\n" + "=============\n");
                    for (var j = 0; j < 3; j++)
                    {
                        var sp = new SamplePairs();
                        var estimatedlength = sp.DoAnalysis(image, j);
                        var numbytes = image.Height*image.Width*3/8
                                       *estimatedlength;

                        //get the right colour
                        if (j == 0)
                        {
                            colour = "red";
                        }
                        else if (j == 1)
                        {
                            colour = "green";
                        }
                        else
                        {
                            colour = "blue";
                        }

                        //Append the results
                        results.Append("Percentage in " + colour + ": ");

                        //Round and Append results
                        results.Append(Round(estimatedlength*100, 5) + "\n");

                        //and the approximate length (in bytes)
                        results.Append("Approximate length (in bytes) from " + colour + ": "
                                       + Round(numbytes, 5) + "\n");

                        averageresults += estimatedlength;
                        averagelength += numbytes;
                    }

                    //average results
                    results.Append("\nAverage across all groups/colours: " +
                                   Round(averageresults/3*100, 5));
                    results.Append("\nAverage approximate length across all groups/colours: " +
                                   Round(averagelength/3, 5));
                    results.Append("\n\n\n");
                }

                //Laplace graph
                if (mRunLaplaceGraph)
                {
                    results.Append("LAPLACE GRAPH (CSV formatted)\n"
                                   + "==============================\n\n");
                    results.Append(LaplaceGraph.GetCSVGraph(image));
                }

                //Append some new lines to make it look nice
                results.Append("\n\n\n\n");

                mResultsString = results.ToString();
                image.UnlockBits();
            }
            return mResultsString;
        }
예제 #18
0
        /**
         * Generates a CSV formatted string of steganalysis information.
         * <P>
         * The directory passed has all it's image files steganalysed and
         * the results are returned in a comma separated file format. No spaces
         * are used in column headings, and all bar the steganography type are
         * numerical values.
         *
         * @param directory The directory to steganalyse.
         * @param laplacelimit The number of laplace values to write out in total.
         * @return A string containing a csv file of results.
         */
        public string GetCSV(string directory, int laplacelimit)
        {
            //output progress to console
            Console.WriteLine("\n\nCSV Progress: {");
            var files = Directory.GetFiles(directory);
            var fivepercent = (int) Math.Floor((double) files.Length/20);

            var csv = new StringBuilder();

            //add all the headings
            if (mRunRsAnalysis)
            {
                var rsa = new RsAnalysis(2, 2);
                var rflag = "(rs overlapping)";
                string colour;

                //overlapping
                for (var i = 0; i < 3; i++)
                {
                    IEnumerable<string> rnames = rsa.GetResultNames();
                    //get the right colour
                    if (i == 0)
                    {
                        colour = " red ";
                    }
                    else if (i == 1)
                    {
                        colour = " green ";
                    }
                    else
                    {
                        colour = " blue ";
                    }
                    foreach (var rname in rnames)
                    {
                        var aname = rname;
                        var towrite = aname + colour + rflag + ",";
                        towrite = towrite.Replace(' ', '-');
                        csv.Append(towrite);
                    }
                }

                //non overlapping
                rflag = "(rs non-overlapping)";
                for (var i = 0; i < 3; i++)
                {
                    IEnumerable<string> rnames = rsa.GetResultNames();
                    //get the right colour
                    if (i == 0)
                    {
                        colour = " red ";
                    }
                    else if (i == 1)
                    {
                        colour = " green ";
                    }
                    else
                    {
                        colour = " blue ";
                    }
                    foreach (var rname in rnames)
                    {
                        var aname = rname;
                        var towrite = aname + colour + rflag + ",";
                        towrite = towrite.Replace(' ', '-');
                        csv.Append(towrite);
                    }
                }
            }
            if (mRunSamplePairs)
            {
                string colour;

                //overlapping
                for (var i = 0; i < 3; i++)
                {
                    //get the right colour
                    if (i == 0)
                    {
                        colour = "-red-";
                    }
                    else if (i == 1)
                    {
                        colour = "-green-";
                    }
                    else
                    {
                        colour = "-blue-";
                    }
                    csv.Append("SP-Percentage" + colour + ",");
                    csv.Append("SP-Approximate-Bytes" + colour + ",");
                }
            }
            if (mRunLaplaceGraph)
            {
                for (var i = 0; i < laplacelimit; i++)
                {
                    csv.Append("Laplace-value-" + i + ",");
                }
            }
            csv.Append("Steganography-Type,Image-Name\n");

            //check all the files
            for (var i = 0; i < files.Length; i++)
            {
                //print progress
                if (i > 0 && fivepercent > 0)
                {
                    if (i%fivepercent == 0)
                    {
                        Console.WriteLine("#");
                    }
                }

                if (files[i].EndsWith(".bmp") || files[i].EndsWith(".png")
                    || files[i].EndsWith(".jpg"))
                {
                    //file can be worked on.

                    string flag;

                    try
                    {
                        using (var bitmap = new Bitmap(files[i]))
                        {
                            var image = new LockBitmap(bitmap);
                            image.LockBits();

                            //run RS analysis
                            if (mRunRsAnalysis)
                            {
                                //overlapping
                                for (var j = 0; j < 3; j++)
                                {
                                    var rsa = new RsAnalysis(2, 2);
                                    var testresults =
                                        rsa.DoAnalysis(image, j, true);

                                    for (var k = 0; k < testresults.Length; k++)
                                    {
                                        csv.Append(testresults[k] + ",");
                                    }
                                }
                                //non-overlapping
                                for (var j = 0; j < 3; j++)
                                {
                                    var rsa = new RsAnalysis(2, 2);
                                    var testresults =
                                        rsa.DoAnalysis(image, j, false);

                                    for (var k = 0; k < testresults.Length; k++)
                                    {
                                        csv.Append(testresults[k] + ",");
                                    }
                                }
                            }

                            //run Sample Pairs
                            if (mRunSamplePairs)
                            {
                                //overlapping
                                for (var j = 0; j < 3; j++)
                                {
                                    var sp = new SamplePairs();
                                    var estimatedlength = sp.DoAnalysis(image, j);
                                    var numbytes = image.Height*image.Width*3/8
                                                   *estimatedlength;
                                    csv.Append(estimatedlength + "," + numbytes + ",");
                                }
                            }

                            //run LaplaceGraph
                            if (mRunLaplaceGraph)
                            {
                                var lgres = LaplaceGraph.GetGraph(image);

                                for (var j = 0; j < laplacelimit; j++)
                                {
                                    if (lgres.Length <= laplacelimit && j >= lgres.Length)
                                    {
                                        csv.Append("0,");
                                    }
                                    else
                                    {
                                        if (lgres[j][0] != j)
                                        {
                                            csv.Append("0,");
                                        }
                                        else
                                        {
                                            csv.Append(lgres[j][1] + ",");
                                        }
                                    }
                                }
                            }

                            if (files[i].IndexOf("_") >= 0 || files[i].IndexOf("-") >= 0)
                            {
                                if (files[i].IndexOf("_") >= 0)
                                {
                                    flag = files[i].Substring(files[i].IndexOf("_") + 1, files[i].LastIndexOf("."));
                                }
                                else
                                {
                                    flag = files[i].Substring(files[i].IndexOf("-") + 1, files[i].LastIndexOf("."));
                                }
                            }
                            else
                            {
                                flag = "none";
                            }

                            csv.Append(flag);
                            //Append in the file name
                            csv.Append("," + files[i]);

                            if (csv[csv.Length - 1] == ',')
                            {
                                csv.Remove(csv.Length - 1, 1);
                            }

                            csv.Append("\n");
                            image.UnlockBits();
                        }
                    }
                    catch (Exception)
                    {
                        //skip the file...
                    }
                    //cleanup to speed up memory
                    GC.Collect();
                }
            }

            //all done
            Console.WriteLine("} Complete!");

            csv.Append("\n");
            return csv.ToString();
        }
예제 #19
0
        /**
         * Creates an ARFF file of steganography information.
         * <P>
         * An ARFF file is the natural internal format for WEKA - Waikato
         * Environment for Knowledge Analysis.  WEKA can also handle CSV
         * files but it is much nicer to be able to produce the natural format.
         * The same information as per the CSV generator is produced here, just
         * in a different format.
         *
         * @param directory The directory to steganalyse.
         * @param laplacelimit The maximum number of laplace values to output.
         * @param relationname The internal name of the relation as it will be
         * seen in WEKA.
         * @return An ARFF formatted file full of the steganalysis information.
         * @see www.cs.waikato.ac.nz/ml/weka
         *
         */
        public string GetARFF(string directory, int laplacelimit, string relationname)
        {
            var arff = new StringBuilder();

            //output progress to console
            Console.WriteLine("\n\nARFF Progress: {");
            var files = Directory.GetFiles(directory);
            var fivepercent = (int) Math.Floor((double) files.Length/20);

            arff.Append("% Steganography Benchmarking Data\n%\n");
            arff.Append("% Sourced from automatic generation in Digital Invisible Ink Toolkit\n");
            arff.Append("% Generator created by Kathryn Hempstalk.\n");
            arff.Append("% Generator copyright under the Gnu General Public License, 2005\n");
            arff.Append("\n");

            arff.Append("\n@relation '" + relationname + "'\n\n");

            //add all the headings
            if (mRunRsAnalysis)
            {
                var rsa = new RsAnalysis(2, 2);
                var rflag = "(rs overlapping)";
                string colour;

                //overlapping
                for (var i = 0; i < 3; i++)
                {
                    IEnumerable<string> rnames = rsa.GetResultNames();
                    //get the right colour
                    if (i == 0)
                    {
                        colour = " red ";
                    }
                    else if (i == 1)
                    {
                        colour = " green ";
                    }
                    else
                    {
                        colour = " blue ";
                    }
                    foreach (var rname in rnames)
                    {
                        var aname = rname;
                        var towrite = aname + colour + rflag;
                        arff.Append("@attribute '" + towrite + "' numeric\n");
                    }
                }

                //non overlapping
                rflag = "(rs non-overlapping)";
                for (var i = 0; i < 3; i++)
                {
                    IEnumerable<string> rnames = rsa.GetResultNames();
                    //get the right colour
                    if (i == 0)
                    {
                        colour = " red ";
                    }
                    else if (i == 1)
                    {
                        colour = " green ";
                    }
                    else
                    {
                        colour = " blue ";
                    }
                    foreach (var rname in rnames)
                    {
                        var aname = rname;
                        var towrite = aname + colour + rflag;
                        arff.Append("@attribute '" + towrite + "' numeric\n");
                    }
                }
            }
            if (mRunSamplePairs)
            {
                string colour;

                //overlapping
                for (var i = 0; i < 3; i++)
                {
                    //get the right colour
                    if (i == 0)
                    {
                        colour = " red ";
                    }
                    else if (i == 1)
                    {
                        colour = " green ";
                    }
                    else
                    {
                        colour = " blue ";
                    }
                    arff.Append("@attribute 'SP Percentage" + colour + "' numeric\n");
                    arff.Append("@attribute 'SP Approximate Bytes" + colour + "' numeric\n");
                }
            }
            if (mRunLaplaceGraph)
            {
                for (var i = 0; i < laplacelimit; i++)
                {
                    arff.Append("@attribute 'Laplace value " + i + "' numeric\n");
                }
            }

            arff.Append("@attribute 'Steganography Type' {");
            //iterate through all the hashmap values...
            var stegotypes = GetStegTypes(Directory.GetFiles(directory));
            var valuesarray = stegotypes.Values.ToArray();
            arff.Append(valuesarray[0]);
            for (var i = 1; i < valuesarray.Length; i++)
            {
                arff.Append("," + valuesarray[i]);
            }
            arff.Append("}\n");
            arff.Append("@attribute 'Image Name' string\n");

            arff.Append("\n@data\n");

            //check all the files
            for (var i = 0; i < files.Length; i++)
            {
                //print progress
                if (i > 0 && fivepercent > 0)
                {
                    if (i%fivepercent == 0 && i != 0)
                    {
                        Console.WriteLine("#");
                    }
                }

                if (files[i].EndsWith(".bmp") || files[i].EndsWith(".png")
                    || files[i].EndsWith(".jpg"))
                {
                    //file can be worked on.

                    try
                    {
                        using (var bitmap = new Bitmap(files[i]))
                        {
                            var image = new LockBitmap(bitmap);
                            image.LockBits();

                            //run RS analysis
                            if (mRunRsAnalysis)
                            {
                                //overlapping
                                for (var j = 0; j < 3; j++)
                                {
                                    var rsa = new RsAnalysis(2, 2);
                                    var testresults =
                                        rsa.DoAnalysis(image, j, true);

                                    for (var k = 0; k < testresults.Length; k++)
                                    {
                                        arff.Append(testresults[k] + ",");
                                    }
                                }
                                //non-overlapping
                                for (var j = 0; j < 3; j++)
                                {
                                    var rsa = new RsAnalysis(2, 2);
                                    var testresults =
                                        rsa.DoAnalysis(image, j, false);

                                    for (var k = 0; k < testresults.Length; k++)
                                    {
                                        arff.Append(testresults[k] + ",");
                                    }
                                }
                            }

                            //run Sample Pairs
                            if (mRunSamplePairs)
                            {
                                //overlapping
                                for (var j = 0; j < 3; j++)
                                {
                                    var sp = new SamplePairs();
                                    var estimatedlength = sp.DoAnalysis(image, j);
                                    var numbytes = image.Height*image.Width*3/8
                                                   *(estimatedlength/100);
                                    arff.Append(estimatedlength + "," + numbytes + ",");
                                }
                            }

                            //run LaplaceGraph
                            if (mRunLaplaceGraph)
                            {
                                var lgres = LaplaceGraph.GetGraph(image);

                                for (var j = 0; j < laplacelimit; j++)
                                {
                                    if (lgres.Length <= laplacelimit && j >= lgres.Length)
                                    {
                                        arff.Append("0,");
                                    }
                                    else
                                    {
                                        if (lgres[j][0] != j)
                                        {
                                            arff.Append("0,");
                                        }
                                        else
                                        {
                                            arff.Append(lgres[j][1] + ",");
                                        }
                                    }
                                }
                            }

                            string flag;
                            if (files[i].IndexOf("_") >= 0 || files[i].IndexOf("-") >= 0)
                            {
                                if (files[i].IndexOf("_") >= 0)
                                {
                                    flag = files[i].Substring(files[i].IndexOf("_") + 1, files[i].LastIndexOf("."));
                                }
                                else
                                {
                                    flag = files[i].Substring(files[i].IndexOf("-") + 1, files[i].LastIndexOf("."));
                                }
                            }
                            else
                            {
                                flag = "none";
                            }

                            arff.Append(flag);
                            arff.Append("," + files[i]);

                            if (arff[arff.Length - 1] == ',')
                            {
                                arff.Remove(arff.Length - 1, 1);
                            }

                            arff.Append("\n");
                            image.UnlockBits();
                        }
                    }
                    catch (Exception)
                    {
                        //skip the file...
                    }
                    //cleanup to speed up memory
                    GC.Collect();
                }
            }

            //all done
            Console.WriteLine("} Complete!");

            return arff.ToString();
        }
예제 #20
0
        /**
         * Does sample pairs analysis on an image.
         *
         * @param image The image to analyse.
         */
        public double DoAnalysis(LockBitmap image, int colour)
        {
            //get the images sizes
            int imgx = image.Width, imgy = image.Height;

            int startx = 0, starty = 0;
            var apair = new Color[2];
            int u, v;
            long P, X, Y, Z;
            long W;

            P = X = Y = Z = W = 0;

            //pairs across the image
            for (starty = 0; starty < imgy; starty++)
            {
                for (startx = 0; startx < imgx; startx = startx + 2)
                {
                    //get the block of data (2 pixels)
                    apair[0] = image.GetPixel(startx, starty);
                    apair[1] = image.GetPixel(startx + 1, starty);

                    u = GetPixelColour(apair[0], colour);
                    v = GetPixelColour(apair[1], colour);

                    //if the 7 msb are the same, but the 1 lsb are different
                    if ((u >> 1 == v >> 1) && ((v & 0x1) != (u & 0x1)))
                        W++;
                    //if the pixels are the same
                    if (u == v)
                        Z++;
                    //if lsb(v) = 0 & u < v OR lsb(v) = 1 & u > v
                    if ((v == (v >> 1) << 1) && (u < v) || (v != (v >> 1) << 1) && (u > v))
                        X++;
                    //vice versa
                    if ((v == (v >> 1) << 1) && (u > v) || (v != (v >> 1) << 1) && (u < v))
                        Y++;
                    P++;
                }
            }

            //pairs down the image
            for (starty = 0; starty < imgy; starty = starty + 2)
            {
                for (startx = 0; startx < imgx; startx++)
                {
                    //get the block of data (2 pixels)
                    apair[0] = image.GetPixel(startx, starty);
                    apair[1] = image.GetPixel(startx, starty + 1);

                    u = GetPixelColour(apair[0], colour);
                    v = GetPixelColour(apair[1], colour);

                    //if the 7 msb are the same, but the 1 lsb are different
                    if ((u >> 1 == v >> 1) && ((v & 0x1) != (u & 0x1)))
                        W++;
                    //the pixels are the same
                    if (u == v)
                        Z++;
                    //if lsb(v) = 0 & u < v OR lsb(v) = 1 & u > v
                    if ((v == (v >> 1) << 1) && (u < v) || (v != (v >> 1) << 1) && (u > v))
                        X++;
                    //vice versa
                    if ((v == (v >> 1) << 1) && (u > v) || (v != (v >> 1) << 1) && (u < v))
                        Y++;
                    P++;
                }
            }

            //solve the quadratic equation
            //in the form ax^2 + bx + c = 0
            var a = 0.5*(W + Z);
            double b = 2*X - P;
            double c = Y - X;

            //the result
            double x;

            //straight line
            if (a == 0)
                x = c/b;

            //curve
            //take it as a curve
            var discriminant = Math.Pow(b, 2) - 4*a*c;

            if (discriminant >= 0)
            {
                var rootpos = (-1*b + Math.Sqrt(discriminant))/(2*a);
                var rootneg = (-1*b - Math.Sqrt(discriminant))/(2*a);

                //return the root with the smallest absolute value (as per paper)
                if (Math.Abs(rootpos) <= Math.Abs(rootneg))
                    x = rootpos;
                else
                    x = rootneg;
            }
            else
            {
                x = c/b;
            }

            if (x == 0)
            {
                //let's assume straight lines again, something is probably wrong
                x = c/b;
            }

            return x;
        }
예제 #21
0
 public Laplace(LockBitmap image, int startbits, int endbits)
     : base(image, startbits, endbits)
 {
 }
예제 #22
0
        /**
         * Gets the laplace graph of an image.  The image
         * is assumed to be colour, no negative values will
         * result.
         *
         * @param image The image to get the graph of.
         * @return The graph of the image.
         */
        public static double[][] GetGraph(LockBitmap image)
        {
            var filter = new Laplace(image, 0, 8);

            //filter the image
            var fparray =
                new FilteredPixel[image.Width*image.Height];
            for (var i = 0; i < image.Width; i++)
            {
                for (var j = 0; j < image.Height; j++)
                {
                    fparray[i*image.Height + j] =
                        new FilteredPixel(i, j,
                            Math.Abs(filter.GetValue(i, j)));
                }
            }

            //sort the filter results
            //is in ascending order - low at start, high at end
            Array.Sort(fparray, new FpComparator());

            //now for each individual filter result, we count how many we have

            //first find out how many different values we have
            var numdistinct = 1;
            for (var i = 1; i < fparray.Length; i++)
            {
                if (fparray[i].FilterValue != fparray[i - 1].FilterValue)
                {
                    numdistinct++;
                }
            }

            //now we create an array to hold the filter values and their counts
            //var results = new double[numdistinct][2];
            var results = new double[numdistinct][];
            for (var i = 0; i < results.Length; i++)
            {
                results[i] = new double[2];
            }
            results[0][0] = fparray[0].FilterValue;
            results[0][1] = 1;
            var k = 0;

            //now we fill up the array
            foreach (var t in fparray)
            {
                if (results[k][0] != t.FilterValue)
                {
                    k++;
                    results[k][0] = t.FilterValue;
                    results[k][1] = 1;
                }
                else
                {
                    results[k][1]++;
                }
            }

            //now normalise the graph
            foreach (var t in results)
            {
                t[1] = t[1]/fparray.Length;
            }

            //graph produced, return results
            return results;
        }