Translate

Wednesday 2 October 2013

Validate an IMAGE File : Is it a REAL IMAGE or a file with Image-Like Clothes ?

It is a great feeling to be back here... Was not able to find time for myself from quite sometime.. : - ( Anyways...
This post s regarding a concern which my colleague Mr X raised while i was doing some creative work in my organization for some event. It required the users to upload their pictures and i have to use them for some further processing on an existing application.

The limitation I had was: the existing processing application was written by someone else and He was unavailable with us now.   That app was designed (don't know how and why) to work for .gif files only.

So i had two options: either ask for photographs from everyone in any format and convert them ( i mean manually renaming them to my desired format.. haha i know its cheating), Or asking them to send ONLY the desired format.

I opted for second . Also the pic-collecting app need to be on INTRANET so 1000 people using and uploading large files was a concern...  (I know this as I also used to do it when someone make his app up for some thing... haha.. doing their STRESS testing. :p..)
The approach to validate the input pictures i took was to check the FIleExtension of the input file.
This is what I have seen in many places and I found it very right and then Mr X, renamed a Doc file as GIF and uploaded on my app. My APP considered it to be ALL RIGHT (due to .gif extn). But when i opened it , the photo viewer displayed :"Nothing to Display". And Mr X asked me to Work Out Something that will check for a REAL IMAGE file and Not a File wearing Clothes like  an IMAGE.  I googled and found very good articles and collated them here to have the various techniques to check/validate a real image.

Below are the various techniques to validate the input files:

1.  Check the Image File Extension
This is a very lame technique but If you are sure that users will only upload REAL Image files then you can use this simple approach to validate your input image in a desired format: The code for the same s here:


 



The Other two approached, which I found very fascinated, were to check for Codes of Image files for some hexadecimal codes and then concluding the Image format for the Input Image. Before discussing the techniques, lets have a brief of the background:

[ the below details are copied shamelessly from few different source..  ;-) ]



·         JPEG format:
The bit sequence for a valid JPEG file should be like this:
Byte
1
2
3
4
5
6
7
8
9
10
11
Hex
FF
D8
FF
E0
Skip
Skip
4A
46
49
46
00
Char
Ÿ
Ø
ÿ
À
Skip
Skip
J
F
I
F

   
The point of notice are the RED and GREEN one's highlighted above.

 The first part to look at is the first two bytes of the file. The hex values FF D8 will identify the start of the image file.  This is often enough to know that you have an actual JPEG file.  The next two bytes are the Application marker typically FF E0This marker can change depending on the application used to modify or save the image .Someone has quoted "  I have seen this marker as FF E1 when pictures were created by Canon digital cameras. "
The next two bytes are skipped.  Read the next five bytes to identify specifically the application marker.  This would typically be 4A 46 49 46 (JFIF) and 00 to terminate the string.  Normally this zero terminated string will be "JFIF" but using the previous example of Canon digital cameras this string will be 45 78 69 66 (Exif)


·         TIFF: TAG IMAGE FILE format:
The bit sequence for a valid TIFF file should be like this:

Byte
1
2
3
Hex
49
49
2A
Char
I
I
*

The TIFF image format was designed to become a standard in image file exchange.  Even though it is widely used it never did become the standard that was envisioned.  Most commonly now you might see this format used by document scanners.  The image header for a TIFF image is a fixed 8 byte segment always occurring at the beginning of the file.  To ensure TIFF images can be read properly by PC's (Intel processors) and Macintosh computers the header must indicate a byte order which in this case is the first two bytes of the file.  The first two bytes will either be hex 49 49 (II) for Intel format or 4D 4D (MM) for the Macintosh integer format which was based on Motorola processors.  The next byte is 2A (decimal 42).  This number should never change.

·         BMP format

The bit sequence for a valid BMP file should be like this
Byte
1
2
Hex
42
4D
Char
B
M

·         GIF (Graphics Interchange Format)
The bit sequence for a valid GIF file should be like this

A GIF file (pronounced as "jiff") is a compressed image format.  It uses lossless data compression which is also used in zip and gzip functions.  Lossless data compression ensures that there is no data loss or image degradation.  GIF files are largely used for animated images and in the early years of the internet you would be hard pressed to find a website not using some form of animated GIF file.
To identify the GIF file read the first three bytes of the file.
Byte
1
2
3
Hex
47
49
46
Char
G
I
F



The Approach 2 may or may not be using the above described code check, I AM STILL IN SEARCH of the LOGIC..for this approach....!!!
But
 Approach 3 checks the CODE of HEADERS...

Now we are having two approaches

First is to Open/ Load a file into memory and then check Whether it is a valid File and Other is to check the header of the files without opening them.

The former approach is though MEMORY CONSUMING but a more reliable than Latter.

2. Load and Check for a valid File
 (  Memory consuming but more Reliable approach )

The below code snippet will load a file and throws an exception if it is not a valid Format of Image:



So just handle the exception and You got your problem resolved.


The various other options available for Image formats are:-





3. Check the header of input image file

The below code looks for the first two bytes and then other two bytes to check for a valid JPEG image.



So the expected comparison of the first two bytes should be:
BMP
0x4d42
JPG
0xd8ff
PNG
0x5089
GIF
0x4947
TIF
0x4949

Lets make it a to VS and do some work...

I have few files with me:


And I have tried to fetch the first byte of their header to consider them as identifier for distinguish purposes.

The code goes here:



The output is:


The appropriate comparison will give us the right validation check.

As far as File Size is concerned:

I have used:
int filesize = FileUpload1.PostedFile.ContentLength;

Now a
if (filesize >= maxsize )


where maxSize is MaxNoOfBytes...   can make you raise a warning..   :-)

For few more  operations on Images see Dot Net Perls for Image

Monday 25 February 2013

Desktop Gadgets not displaying properly in Windows-7 and Vista

Hi All,

Its time to share a solution again. 

I restored my laptop 15 days ago or so.. and then never used gadgets , but today when i tried to use them, i  found my desktop gadgets behaving weirdly

The clock appears alien with black background and a red line in between.
Tried to search through the internet for this solution.  Found few links , which asks me to play with the registry of windows, to which i am most reluctant.

Banged my head again and again and finally found a solution to it.  This is the link to the forum.

Windows Desktop Gadgets appearing Alien  ::D

I tried the Case-II of the mentioned solution and..

And it simply...  
.
.
.
.
.


... WORKED..!!!!



And a discussion pointed on the symptoms of such problem was explained at:
http://support.microsoft.com/kb/2515657


Another Discussion:
-- http://social.technet.microsoft.com/Forums/en-US/w7itproappcompat/thread/a429da8e-6e39-4e0c-ba5b-921441237079/

--

Thursday 24 January 2013

“Decimal not displaying in SUM” Issue in DevExpress XtraReport.

Hi.. I AM back again..  :).. This time with a concern which i faced at my work place while working on DevXpress XtraReport tool.

XtraReport is a tool used for generating reports. The Issue was: When i apply the SUM function of XtraReport on Some column data then i was facing concerns of my trailing zeroes getting compressed and for a finance domain client: Rs25,000.00 looks better than Rs25,000.. He He..

The Summary Functions provided by XtraReport includes: Aggregate,Sum,DCount(Distinct Count) etc..

For Eg: I have applied a SUM function on a label , bound to print Sum of a Column that has No.Of Shares.
The data at some instance of time in column is: 2.00,3.00,32.08,29.02,123.9

The Sum Function Gives me : 190 instead of 190.00 as its default behavior considers this number as integer and eats the Trailing zeroes.. But If the Output is Something of sort of 125.00256 then it displayes it with correct decimals But if the output is 2563.36200, then also it displays it like 2563.362.

After prolonged discussion on DevExpress XtraReport on Various forums.. I found the solution..

Steps:
Change the Summary_Function type of the XRLabel to CUSTOM:

Now Write Code on the following event:
And write the following Code:


private void xrLabel10_SummaryGetResult(object sender, SummaryGetResultEventArgs e)
        {           
            int decimalCount = 0; 
            double sumOfValues = 0;
            string formatString = String.Empty;
            foreach (var value in e.CalculatedValues)
            {
                if (Convert.ToString(value) != String.Empty)   //check for null values
                {
                    sumOfValues = sumOfValues + Convert.ToDouble(value);   //calculate the sum of values
                      if (Convert.ToString(value).Split('.').Length == 2)  //check for only one decimal Place in data
                          if (Convert.ToString(value).Split('.')[1].Length > decimalCount) //calculating number of decimal places
                                decimalCount = Convert.ToString(value).Split('.')[1].Length;                   
                }
            }
            formatString = formatString.PadRight(decimalCount, '0');     
            e.Result =sumOfValues.ToString("#,##0." + formatString);  //thousand separator + decimal Count
            e.Handled = true;
        }


Hence i over-ride the default behavior of the Method to Solve this Issue.. And beleive me.. It Solved many Similar Concerns for my Client...


Wednesday 23 January 2013

RSA Cryptographic Algorithm- Implemented in C#

Symmetric Encryption Technique: PLAYFAIR:

As wiki says:

The Playfair cipher or Playfair square is a manual symmetric encryption technique and was the first literal digraph substitution cipher. The scheme was invented in 1854 by Charles Wheatstone, but bears the name of Lord Playfair who promoted the use of the cipher.
The technique encrypts pairs of letters (digraphs), instead of single letters as in the simple substitution cipher and rather more complex Vigenère cipher systems then in use. The Playfair is thus significantly harder to break since the frequency analysis used for simple substitution ciphers does not work with it. Frequency analysis can still be undertaken, but on the 600[1] possible digraphs rather than the 26 possible monographs. The frequency analysis of digraphs is possible, but considerably more difficult – and it generally requires a much larger ciphertext in order to be useful.

See:wiki-Playfair_cipher for details

I tried it at my end at my college times for network security subject. The C# code for the same is below:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Playfair
{
   
    class Program
    {
        public static char[,] matrix = new char[5, 5];
        public static string cipher = "";
        static void Main(string[] args)
        {
            create_matrix(); // matrix created
          
           
            Console.WriteLine("enter plaintext:  ");

            int p = 0;
            string plaintext = Console.ReadLine();

            string nwplain = plaintext.Replace(" ", "");
            plaintext = nwplain;

            int size = plaintext.Length;



            plaintext = test(size, plaintext);



            if (size % 2 == 1)
            {
                plaintext = plaintext + "x";
            }
            double q = (double)size / 2;
            int s = Convert.ToInt32(Math.Ceiling(q));
            char[,] qw = new char[s, 2];
            for (int i = 0; i <= size - 1; i = i + 2)
            {
                if (plaintext.Substring(i, 1) == "i")
                {
                    qw[p, 0] = 'j';
                }
                else
                {
                    qw[p, 0] = Convert.ToChar(plaintext.Substring(i, 1));
                }

                if (plaintext.Substring(i + 1, 1) != null)
                {
                    if (plaintext.Substring(i + 1, 1) == "i")
                    {
                        qw[p, 1] = 'j';
                    }
                    else
                    {
                   qw[p, 1] = Convert.ToChar(plaintext.Substring(i + 1, 1));
                    }
                }
                p = p + 1;
            }

            for (int i = 0; i < p; i++)
            {
                string posi = pos(qw[i, 0]);
                string[] str = posi.Split('.');
                int[] first = new int[2];
                int[] second = new int[2];
                first[0] = Convert.ToInt32(str[0]);// x pos
                first[1] = Convert.ToInt32(str[1]);// y pos
                posi = pos(qw[i, 1]);
                string[] str1 = posi.Split('.');
                second[0] = Convert.ToInt32(str1[0]);// x pos
                second[1] = Convert.ToInt32(str1[1]);// y pos

                if (first[0] == second[0])// same row
                {
                    if (first[1] == 4)
                    {
                        first[1] = -1;
                    }
                    if (second[1] == 4)
                    {
                        second[1] = -1;
                    }
                    cipher = cipher + matrix[(first[0]), (first[1] + 1)];
                    cipher = cipher + matrix[(second[0]), (second[1] + 1)];

                }
                else if (first[1] == second[1])// same column
                {
                    if (first[0] == 4)
                    {
                        first[0] = -1;
                    }
                    if (second[0] == 4)
                    {
                        second[0] = -1;
                    }
                    cipher = cipher + matrix[(first[0] + 1), (first[1])];
                    cipher = cipher + matrix[(second[0] + 1), (second[1])];
                }
                else
                {
                    cipher = cipher + matrix[first[0], second[1]];
                    cipher = cipher + matrix[second[0], first[1]];


                }
            }
            Console.Write("Cipher Text:");

            Console.WriteLine(cipher.ToUpper());
            string df = Console.ReadLine();

        }// end main


        static string pos(char a)
        {
            string w="";
        for (int i = 0; i < 5; i++)
        {
            for (int j = 0; j < 5; j++)
            {
                if (a == matrix[i, j])
                {
                     w = i.ToString() +"."+ j.ToString();
                     break;
                  
                }
               
            }
        }
        return (w);
        }

        static string test(int size, string pt) //doublet
        {
            ch:
            for (int i = 0; i <=size - 1; i = i + 2)
            {
                if (pt.Substring(i, 1) == pt.Substring(i + 1, 1))
                {
                   pt= pt.Insert(i+1, "x");
                    goto ch;
               
                }
           
            }
          
            return (pt);
        }


        static void create_matrix()
        {
            string k1 = "";
            Console.WriteLine("Enter Key (alphabetic): ");
            string key = Console.ReadLine();
            string reference = "abcdefghjklmnopqrstuvwxyz";
            int size = key.Length;
            string[] key_arry = new string[size];
            for (int i = 0; i < size; i++)
            {
                key_arry[i] = key.Substring(i, 1);
            }

            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    if (i != j)
                    {
                        if (key_arry[i] == "i")
                        {
                            key_arry[i] = "j";
                        }
                        if (key_arry[i] == key_arry[j])
                        {
                            key_arry[j] = "1";
                        }
                    }
                }

            }
            for (int i = 0; i < size; i++)
            {
                k1 = k1 + key_arry[i].ToString();
            }
            k1 = k1.Replace('i', 'j');
            k1 = k1.Replace('1', ' ');
            k1 = k1.Replace(" ", "");
            foreach (string c in key_arry)
            {
                reference = reference.Replace(c, "");

            }
            int si = 0;
            int p=0;
            int len = k1.Length;
            for (int i = 0; i < 5; i++)
            {
               
                for (int j = 0; j < 5; j++)
                {
                    if (si < size)
                    {
                        if (key_arry[si] != "" && key_arry[si] != "1")
                        {                           
                                matrix[i, j] = Convert.ToChar(key_arry[si]);
                          
                            si++;
                        }
                        else
                        {
                            si++;
                            j--;
                        }
                    }
                    else
                    {

                        si++;
                        if (si >= size)
                        {
            matrix[i, j] = Convert.ToChar(reference.Substring(p, 1));
                            j++;
                            p++;
                        }
                        j--;
                    }
                }
              
            }
            Console.WriteLine("THE PLAYFAIR MATRIX IS:");
            for (int i = 0; i < 5; i++)
            {
                Console.Write("\n");
                for (int j = 0; j < 5; j++)
                {
                    Console.Write(" ");

                    Console.Write(matrix[i, j]);

                }
            }
            Console.WriteLine("");

        }


    }// end class program
}//end namespace



The Output:

hope It Helps U...