Monday, 17 February 2014

The Chuck Norris Color

      In HTML specifying "chucknorris" as color makes the element a dark shade of red. As an example the line

<body bgcolor="chucknorris"></body>

will render the background color of the page red. Check it out at http://jsfiddle.net/rvt5f/ . For those who dont know who Chuck Norris is read this wiki article's internet meme section. Trying out various combinations of strings as colors leads to "sick" being rendered as green and "crap" being rendered as brown. So is HTMLS's rendering of the letters "chucknorris" as RED, some sort of a subtle hint about how dangerous World's Greatest Human is? Well, No.

      Just about anything that you can put into the color attribute in HTML will be rendered as some sort of color. This is becuase of the way HTML parses color names. It uses the following algorithm to generate a color value (of the form #dddddd, where d represents a hexadecimal digit) from an invalid color string(see Note #1) :

1. Pad the letters with 0's till the length of the string is a multiple of 3.
So "chucknorris" becomes "chucknorris0"

2. Divide the string into 3 equal parts.
"chucknorris0" = "chuc knor ris0"

3. Replace all non hexadecimal characters with 0's.
"chuc knor ris0" = "c00c 0000 0000"

4. Truncate 2 characters from the right from each substring.
"c00c 0000 0000" = "c0 00 00"
   
So now the colour
#c00000
is rendered which is rendered as a darker shade of red.

Similarly "sick" corresponds to #00c000 (a shade of green) and "crap" corresponds to "#c0a000" (a shade of brown)

"sick" = "sick00"
"sick00" = "si ck 00"
"si ck 00" = "00 c0 00"

"crap" = "crap00"
"crap00" = "cr ap 00"
"cr ap 00" = "c0 a0 00"


Following is a list of invalid strings that render interesting colors :

chucknorris
sick
crap
snow
grass



Note :

1. The above algorithm applies only to strings which are not actual colors(i.e. invalid strings). So when "blue" is given as colour attribute, the element will actually turn out blue rather than "#b00e00"(darkish red) which is obtained by the above method.


"blue" = "blue00"
"blue00" = "bl ue 00"
"bl ue 00" = "b0 0e 00"

Similar is the case for all of the following colours that HTML recognizes :

    Black = "#000000"           Green = "#008000"
    Silver = "#C0C0C0"          Lime = "#00FF00"
    Gray = "#808080"            Olive = "#808000"
    White = "#FFFFFF"          Yellow = "#FFFF00"
    Maroon = "#800000"        Navy = "#000080"
    Red = "#FF0000"              Blue = "#0000FF"
    Purple = "#800080"          Teal = "#008080"
    Fuchsia = "#FF00FF"        Aqua = "#00FFFF"


2. None of the above work if the strings are put in a CSS colour.



Sunday, 12 January 2014

Segmentation Fault - An analysis

      A segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed (for example, attempting to write to a read-only location, or to overwrite part of the operating system). On the operating system level, the process of segmentation divides available memory into segments. When encountering an error in writing to a memory segment, the Unix or Linux operating system sends a SIGSEGV signal to the program, which then crashes with the "segmentation fault" message. A core file may be generated to aid debugging. Segmentation faults can result in the following cases :

     1. When a running program attempts to access a memory location not allocated to it. e.g.
struct Ex
{
    int n;
};
int main()
{
    struct Ex *obj;
    obj->n=5;
}
      Here the pointer obj to struct Ex does not contain a valid object or address, thus it will result in a crash

     2. Accessing a location of memory the program is not permitted to access. An example of this is an attempt to access read only memory.  e.g.
 char *s = "hello world";
 *s = 'H';
      When the above code is compiled, the string "hello world" is placed in the read only section of the program binary. When the program gets executed the program the pointer is is set to point to the strings' location. So far so good. The next line however attempts to write the character 'H' to the memory. Since this memory was read only and we attempted a write, the program crashes with a segmentation fault.

      3. Dereferencing a NULL pointer. e.g.
 int *s = NULL;
 *s = 1;
      In this case an integer pointer is set to NULL. This means that it does not point to anything yet. So when we dereference the pointer and try to set a value 1 to a non-existent memory location we encounter a segmentation fault.

      4. Stack Overflow : On some systems a stack overflow will result in a segmentation fault. An example of this is recursive function without a base case.(which recursion never stops). Fo e.g. the following code causes a segmentation fault because of a stack overflow.
 void recurse()
 {
     recurse();
 }
 int main()
 {
     recurse();
 }

Debugging a segmentation fault


      Looking for a segmentation fault without any tool is a difficult task without the proper tools. One tool which you can use to debug a segmentation fault is the GNU Debugger(gdb). But to use gdb effectively we need to compile our C program with the -g option. The -g option produces debugging information in the operating system's native format.  GDB can further work with this debugging information.

Let us take the example of the following program :
#include<stdio.h>
#include<stdlib.h>
// the program contains an intentional error
// on compilation it may issue a warning which we can ignore for demo purpose
int input_num()
{
        int n;
        int *p=(int *)malloc(sizeof(int));
        scanf("%d",n);
        return n;
}
void input_array(int *a,int n)
{
        int i;
        a = malloc(n*sizeof(int));
        for(i=0;i<n;i++)
                a[i]=input_num();
}
int main()
{
        int *a,n,i;
        n=10;
        input_array(a,10);
        for(i=0;i<n;i++)
                printf("%d",a[i]);
}

      The program is meant to input an array of length 10. The function input_num is used to input a number, and this functions is used by the input_array function to input the array. However the program contains an intentional error which will cause a segmentation fault. The program compiles just fine(maybe with a warning about the error itself, but we can ignore it for demonstration purposes).

Getting your hands dirty : The Debugging!


To begin, compile the program with the -g option.
gcc sigsegv.c -o sigsegv -g -w
The -w option is there to ignore any warnings.

Now use gdb to start the debugger for the output file sigsev(the compiled output file for our program)
rishabh@ubuntu:~/SIGSEGV$ gdb sigsegv 
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/rishabh/SIGSEGV/sigsegv...done.
(gdb)
Next run the program with the run command :
(gdb) run
Starting program: /home/rishabh/SIGSEGV/sigsegv
Input a number : 1

Program received signal SIGSEGV, Segmentation fault.
0xb7e71d73 in _IO_vfscanf () from /lib/i386-linux-gnu/libc.so.6
(gdb) 

Now as you can see we ran into a segmentation fault. Take a backtrace of the program now with the bt command.

(gdb) bt
#0  0xb7e71d73 in _IO_vfscanf () from /lib/i386-linux-gnu/libc.so.6
#1  0xb7e786bb in __isoc99_scanf () from /lib/i386-linux-gnu/libc.so.6
#2  0x0804848b in input_num () at sigsegv.c:7
#3  0x080484c1 in input_array (a=0xb7fc6ff4, n=10) at sigsegv.c:15
#4  0x080484fa in main () at sigsegv.c:21
(gdb)

A backtrace shows the function calls that were made by our program. So we can see that we crashed in the function called _IO_vfscanf (). But we are insterested only in what part of our program triggered this function. Going thrugh the bactrace we can see that the last user defined function called from by our program was input_num (). The "at sigsegv.c:7" just after the function call indicates that this function was executed till before this line, and on this line a function call was made.
Now lets look at this stack frame. Its the frame #2. To view it give the frame command :

(gdb) frame 2
#2  0x0804848b in input_num () at sigsegv.c:7
7        scanf("%d",n);
(gdb)

Now we can see that scanf is the culprit function. We can generally assume that the library functions work correctly. So this means that the fault is with the arguments we passed to the function. Lets print the arguments that were passed to the function with the print command.

(gdb) print n
$1 = -1208193036
(gdb)

Now the scanf function expects an address to an integer variable be passed to it as an argument, but here we see that instead of an address we are passing an integer with a garbage value. This concludes our analysis. We know that that passing this argument in the wrong way caused our segmentation fault. Quit the debugger with the quit command

(gdb) quit

A debugging session is active.

    Inferior 1 [process 4583] will be killed.

Quit anyway? (y or n) y
rishabh@ubuntu:~/SIGSEGV$ 

Another case of a segmentation fault is with the non ending recursive calls. In this case a simple look at the backtrace is enough to find the fault in the program. The following is such a program.

#include<stdio.h>
void recurse()
{
    recurse();
}
int main()
{
    recurse();
}

The following is its debugger output :

rishabh@ubuntu:~/SIGSEGV$ gdb recurse 
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/rishabh/SIGSEGV/recurse...done.
(gdb) run
Starting program: /home/rishabh/SIGSEGV/recurse 

Program received signal SIGSEGV, Segmentation fault.
recurse () at recurse.c:4
4        recurse();
(gdb) bt
#0  recurse () at recurse.c:4
#1  0x080483bf in recurse () at recurse.c:4
#2  0x080483bf in recurse () at recurse.c:4
#3  0x080483bf in recurse () at recurse.c:4
#4  0x080483bf in recurse () at recurse.c:4
#5  0x080483bf in recurse () at recurse.c:4
#6  0x080483bf in recurse () at recurse.c:4
#7  0x080483bf in recurse () at recurse.c:4
#8  0x080483bf in recurse () at recurse.c:4
#9  0x080483bf in recurse () at recurse.c:4
#10 0x080483bf in recurse () at recurse.c:4
#11 0x080483bf in recurse () at recurse.c:4
#12 0x080483bf in recurse () at recurse.c:4
#13 0x080483bf in recurse () at recurse.c:4
#14 0x080483bf in recurse () at recurse.c:4
#15 0x080483bf in recurse () at recurse.c:4
#16 0x080483bf in recurse () at recurse.c:4
#17 0x080483bf in recurse () at recurse.c:4
#18 0x080483bf in recurse () at recurse.c:4
#19 0x080483bf in recurse () at recurse.c:4
#20 0x080483bf in recurse () at recurse.c:4
#21 0x080483bf in recurse () at recurse.c:4
#22 0x080483bf in recurse () at recurse.c:4
#23 0x080483bf in recurse () at recurse.c:4
#24 0x080483bf in recurse () at recurse.c:4
#25 0x080483bf in recurse () at recurse.c:4
#26 0x080483bf in recurse () at recurse.c:4
#27 0x080483bf in recurse () at recurse.c:4
#28 0x080483bf in recurse () at recurse.c:4
#29 0x080483bf in recurse () at recurse.c:4
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) q
A debugging session is active.

    Inferior 1 [process 4710] will be killed.

Quit anyway? (y or n) y
rishabh@ubuntu:~/SIGSEGV$ 

Debugging a CORE file :


      Debugging a generated core file is also possible in a similar way. The steps are as follows :

1. Compile the program with the -g option.
2. Give the "ulimit -c unlimited" command to enable Linux to core-dump on a segmentation fault.
3. Run the program normally.
4. Debug the program with the gdb command "gdb <executable-name> <core-file>" The following is the debugging of the array program through a core file :

rishabh@ubuntu:~/SIGSEGV$ gcc sigsegv.c -o sigsegv -g -w
rishabh@ubuntu:~/SIGSEGV$ ulimit -c unlimited
rishabh@ubuntu:~/SIGSEGV$ ./sigsegv 
Input a number : 1
Segmentation fault (core dumped)
rishabh@ubuntu:~/SIGSEGV$ ls
core  recurse  recurse.c  sigsegv  sigsegv.c
rishabh@ubuntu:~/SIGSEGV$ gdb sigsegv core
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/rishabh/SIGSEGV/sigsegv...done.

warning: exec file is newer than core file.
[New LWP 5059]

warning: Can't read pathname for load map: Input/output error.
Core was generated by `./sigsegv'.
Program terminated with signal 11, Segmentation fault.
#0  0xb7667d73 in _IO_vfscanf () from /lib/i386-linux-gnu/libc.so.6
(gdb) bt
#0  0xb7667d73 in _IO_vfscanf () from /lib/i386-linux-gnu/libc.so.6
#1  0xb766e6bb in __isoc99_scanf () from /lib/i386-linux-gnu/libc.so.6
#2  0x0804848b in input_num () at sigsegv.c:7
#3  0x080484c1 in input_array (a=0xb77bcff4, n=10) at sigsegv.c:15
#4  0x080484fa in main () at sigsegv.c:21
(gdb) frame 2
#2  0x0804848b in input_num () at sigsegv.c:7
7  scanf("%d",n);
(gdb) print n
$1 = -1216622604
(gdb) q
rishabh@ubuntu:~/SIGSEGV$ 

Wednesday, 1 January 2014

Fast Input/Output in C

      Certain problems on competitive programming sites such as Codechef, SPOJ etc. specify warnings  such as : Warning: large Input/Output data, be careful with certain languages (though most should be OK if the algorithm is well designed). Usually all such problems can be solved by using the scanf and printf library functions. But there do exist methods which are much faster than these which yield a better execution time. An example is the getchar_unlocked() function. It can be argued that scanf provides a lot of security checks that should be there for any robust program facing real world inputs, but in the world of competitive programing, where the input is properly defined, we can safely ignore such checks for getting around tighter timing constraints and getting a much lesser execution time.

The getchar_unlocked() method :

int getchar_unlocked(void);

      The function reads the next character from stdin stream  and  returns  it  as  an unsigned char cast to an int, or EOF on end of file or error. The "_unlocked" differentiates it from the getchar() function in the sense that getchar_unlocked() does not use locking (it  do  not  set  locks itself, and does not test for the presence of locks set by others) and hence is thread-unsafe, but it works perfectly fine in single-threaded programs (like the ones submitted to SPOJ/Codechef). However it is much faster than both scanf() and getchar(), and thus can provide considerable improvement in execution time.

      Since the getchar_unlocked() function returns the next character from the stdin stream, we will have to write our own code to process different kinds of input. The following code is capable of accepting positive integers.

int scan_positive_int(int *a)
{
    int x=0;
    register int c=getchar_unlocked();
    for(; c>47 && c<58 ; c = getchar_unlocked())
    {
        x = (x<<1) + (x<<3) + c - 48;
    }
    *a=x;
}

Explanation :

1. The keyword register hints to compiler that a given variable can be put in a register. It’s compiler’s choice to put it in a register or not. Since register are faster to access than memory we can use them for taking input.

2. The expression "(x<<1)+(x<<3)" is equivalent to "x*10" . This is because of the following :
x*10 = x*(2+8)
        = (x*2)+(x*8)
        = (x<<1)+(x<<3)   (Because left shift of x by n is equivalent to x*2^n, so x<<3 is equivalent to x*8 and x<<1 is equivalent to x*2)
   
3. The statement x = (x<<1) + (x<<3) + c – 48; thus is equivalent to x = x * 10 + c -48 ; It will append the input character to the end of the integer x. (Eg. Suppose x is 2 and the input character is 1, then the statement becomes x = 2*10 + 1, thus giving x the value 21).

4.  The for loop after this takes a single character as input from the stdin stream and checks whether this character is an integer, and if it is then it appends the character to x, thus forming the number. The loop exits whenever a non-digit character is encountered.

Similar functions can be written for accepting integers and strings. A function that is capable of handling both positive and negative integers is given below :

int scan_int(int *a)
{
    int x=0,negative=0;
    register int c=getchar_unlocked();
    if(c=='-')
    {
        negative=1;
    c=getchar_unlocked();
    }    
    for(; c>47 && c<58 ; c = getchar_unlocked())
    {
        x = (x<<1) + (x<<3) + c - 48;
    }
    *a=(negative==1)?-(x):x;
}

The performance of above code can be tested with the INTEST problem on SPOJ. A code with scanf() statements for input yielded an execution time of 5.53 sec while the solution containing the above method using getchar_unlocked() for input took only 0.86 seconds.

The respective codes are :

1. Using scanf() : Exec time 5.53 sec

#include<stdio.h>
int main()
{
    int n,k,t,count=0;
    scanf("%d",&n);
    scanf("%d",&k);
    while(n>0)
    {
        n--;
        scanf("%d",&t);
        if(t%k==0)
            count++;
    }
    printf("%d",count);
    return 0;
}


2. Using getchar_unlocked() : Exec time 0.86 sec

#include<stdio.h>
int scan_positive_int(int *a)
{
        int x=0;
        register int c=getchar_unlocked();
        for(; c>47 && c<58 ; c = getchar_unlocked())
        {
                x = (x<<1) + (x<<3) + c - 48;
        }
        *a=x;
}
int main()
{
    int n,k,t,count=0;
    scan_positive_int(&n);
    scan_positive_int(&k);
    while(n>0)
    {
        n--;
        scan_positive_int(&t);
        if(t%k==0)
            count++;
    }
    printf("%d",count);
    return 0;
}


      I have tested the above codes on Ubuntu. On windows getchar_unlocked() will have to replaced with getchar() to make the above codes work. The getchar() function is slower than getchar_unlocked() because it provides the additional security of being threadsafe.So if you are using windows then you can test your code using getchar() and replace it with getchar_unlocked() before submitting it to Codechef/SPOJ.

Sunday, 21 July 2013

Determine if any anagram of a string can be a palindrome.

The Problem : 

      Given a string containing only lowercase alphabets, determine whether an anagram of this string can be a palindrome. Output YES if an anagram which is a palindrome exists and NO otherwise. The length of the string can vary between 1 and 100000, both inclusive.

Examples :

Input String : aab
Output : YES
Explanation : aba is an anagram which is a palindrome

Input String : babb
Output : NO
Explanation : No anagram of "babb" exist which is a palindrome

Input String : a
Output : YES
Explanation : a is itself a palindrome

Input String :bbabaaa
Output : YES
Explanation aabbbaa is an anagram which is a palindrome


The Solution : 

      A brute force way of solving this would be to generate all anagrams of the given string and then check whether any of them is a palindrome. But a string of length n (of distinct characters) can have n! different anagrams. Thus this method is not feasible even for small values of n (5!=120, 10!=3628800). A faster solution is thus needed.

      Lets look at an even length string. For this to be a palindrome the first half of the string must match the second half. So each characters in the first half of the string must also be present in the second half. Hence, there must be an even number of occurrences of each character in the string. (Note that here we say even occurrences of each character and not 2 occurrences. Why?. Consider the case where we have 4 occurrences of character 'a'. This means two of them can lie in the first half and the other two in the second half, hence an even number of occurrences is acceptable).

      Now lets take the case of an odd length string. Here the middle character of the string can be anything. Only the former part of the string (before the middle character) must match the latter part(after the middle character). So the middle character does not need a matching character, but the rest of the characters must occur in pairs (i.e. each character other than the middle must occur an even number of times in the string).

Now, for the problem at hand.

Case 1: Even length string 
   
      If each character of the string occurs an even number of times then we can make a palindrome out of it by rearranging the characters. For each character in the first half there shall exist a matching one in the second half. So we just need to count the occurrence of each character. If each character occurs an even number of times we can print YES.

Case 2: Odd length string

      Here, in a palindrome, all characters must have a matching pair except the middle one. So each character must occur an even number of times except one. So in a random string if all characters except one occur an even number of times, then these characters can be arranged in the first and second halves of the string. Now for the character that occurs an odd number of times. Suppose it occurs 5 times. Then 4 occurrences of this can be included in the first and second halves of the palindrome and the remaining one occurrence will become the middle character.
       Note that if, in a string, we had more than one character occurring an odd number of times the we could not have created a palindrome out of it.

So the logic becomes :

If string is of even length, check if all characters occur an even number of times, if they do print YES else print NO.

If string is of odd length, check if all but one characters occur an even number of times, one character must occur odd number of times, if these conditions satisfy print YES else print NO.


The Implementation:

      Here we need to count the occurrence of only 26 lowercase alphabets. So take an array of length 26. The count of 'a' will stored at the zeroth positions, 'b' at the first position and so on. Initialize this array with 0's. Lets call this array a[].

      Now a naive implementation would be to simply go through the string and increment the corresponding position in the array. At the end go through the array to check if the requirements defined in the logic are met. There is however a better solution where we need not traverse the array to get the solution.

      We take a flag variable to indicate the number of characters which occur odd number of times in the string. Every time we encounter a character we shall toggle the corresponding position in the array. Since the initial value of the position was 0, the first time it is toggled, it will become 1. On the next toggle it will become zero. Hence, a value 1 indicates the first occurrence and a value zero indicates the second occurrence. So every time a position becomes 1 increment the flag, and every time it becomes zero decrement the flag.

      So at any point during the traversal of the string the flag will indicate the number of characters whose occurrence count till this point is odd. Lets see this with an example.

Lets take the string ababb. A dry run is shown in the following table

Position   Character           array a[]                flag
   0               a           a[0]=1,others 0                   1    (till this point a-odd)
   1               b           a[1]=1,a[0]=1,others 0       2    (till this point a-odd, b-odd)
   2               a        a[0]=0,a[1]=1,others 0        1    (till this point b-odd)
   3               b a[1]=0,others 0                   0    (till this point none-odd)
   4               b a[1]=1,others 0                   1    (till this point b-odd)


The toggle can be implemented by using the XOR operator " ^ ".

Now to display the result, the following steps are followed :

1. Find length of string
2. If even then if flag=0 print YES esle print NO
3. If odd then if flag=1 print YES else print NO

The Code (in C): 

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
   int a[26],i,flag=0,len=0;
   char str[100001],*ptr=NULL;
   for(i=0;i<26;i++)
   a[i]&=0;
   scanf("%s",str);   //the input
   ptr=str;
   while(*ptr)   //traversing the string
   {
      len++;   //counting the length
      a[*ptr-97]^=1;   //toggle the position for if ptr points to a the a[*ptr-97] translates to a[0]
      if(a[*ptr-97])   //if position became 1
         flag++;
      else   //if position became 0
         flag--;
      ptr++;
   }
   if(len&1)   //if string is of odd length
   {
      if(flag==1)
         printf("YES");
      else
         printf("NO");
   }
   else   //if string is of even length

   {
      if(flag==0)
         printf("YES");
      else
         printf("NO");
   }
   return 0;
}

      Note that if in the problem it was not specified that the contents of the string are lowercase alphabets, then we could take the array to be of length 256 to take into account all the ASCII characters.

Saturday, 20 July 2013

Capture Screenshot/Part of Java GUI

      In this post we shall see how to capture a screenshot with java. Also, we shall see how to capture the GUI (complete with the frame or partial e.g. a graph displayed in a panel) thrown by a Java Program. This may be useful in the case when we have to take a print out of, say, a graph or an image which is displayed on the Graphical User Interface(GUI).

Part 1 : The Screenshot

      To do this we shall make use of the Robot, BufferedImage and ImageIO classes. A brief description of how the classes are used follows :

Robot :  The Robot class has a function called createScreenCapture() which take as parameter a Rectangle object. The Rectangle object specifies the portion of the screen to capture (through coordinates). It returns a BufferedImage object. For taking a screenshot the rectangle must cover the entire screen. We can get the screen size by using the Toolkit.getDefaultToolkit().getScreenSize() method.

BufferedImage :  This class is used to describe an image. We shall store the return value from the call to the createScreenCapture() method of the Robot class in a BufferedImage object. Then this will be used to write a file containing the image using the ImageIO class.

ImageIO : It has a static method called write() which takes three parameters : the image(BufferedImage object), the format of the file to write(e.g. png) and the name of the file.


The CODE : 

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
class ScreenCapture {
   public static void main(String args[]) {
      try {
         Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
         BufferedImage capture = new Robot().createScreenCapture(screenRect);
         ImageIO.write(capture, "png", new File("d:\\screencapture.png"));
      }catch (Exception ex) {
         System.out.println(ex);
      }
   }
}


Part 2 : Cpturing Java GUI

      Now, we shall try to capture the GUI displayed by a Java Swing/AWT program. This can be useful when we have to print the whole layout displayed by a program or print a portion of it (say a graph or an image displayed on it). To do this we shall make use of the BufferedImage and the ImageIO classes. The following points explain the process :

1. Instantiate a BufferedImage object (called capture in our example) using the three argument contructor. The arguments passed are the a) width - width of the created image b) height - height of the created image c) imageType - type of the created image.
2. Call the components paint method(the component whose contents are to be captured). Pass as argument capture.getGraphics(). When the getGraphics() method is called on a component, it returns the component's graphics context, which lets you draw on a component. When this is passed as argument to paint method, the contents of the component calling the paint method(pnl2 in our case) are drawn on the object whose Graphic context is passed as argument.
3. Lastly we use the ImageIO.write() method to write the BufferedImage object to a file.


The CODE : 

Here we display a simple frame with two panels and capture the contents of pnl2 in an image.

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;
public class CapturePanelInFrame extends JFrame {
   JPanel pnl1,pnl2;
   JLabel lab1,lab2;
   public CapturePanelInFrame() {   //Creating the GUI
      pnl1=new JPanel();
      pnl2=new JPanel();
      pnl1.setBackground(Color.blue);
      pnl2.setBackground(Color.green);
      lab1=new JLabel("This is the Label in Panel1");
      lab2=new JLabel("This is the Label in Panel2");
      pnl1.add(lab1);
      pnl2.add(lab2);
      setLayout(new GridLayout(2,1));
      add(pnl1);
      add(pnl2);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setSize(400,200);
      setVisible(true);
      captureit(pnl2);
   }
   private void captureit(JComponent comp) {
      Rectangle rec = comp.getBounds(); // Getting the size of Component
      BufferedImage capture = new BufferedImage(rec.width, rec.height,BufferedImage.TYPE_INT_ARGB);
      comp.paint(capture.getGraphics());//capturing the components content in the capture object
      try {
         ImageIO.write(capture, "png", new File("capturepnl.png")); //writing the captued image to a file
      } catch (Exception e) {
         System.out.println(e);
      }
   }
   public static void main(String args[])
   {
      new CapturePanelInFrame();
   }
}


      Note that we pass the component to be captured to the captureit() method. So if we need to display the whole frame that is to be displayed, we can simply pass the JFrame object.

Saturday, 6 July 2013

Open browser with proxy settings set from Java code

      In this post we aim to to write a java application which lets the user click a button to open a browser with its proxy settings set. To open an application from java we can use the exec method of the java Runtime class. So one can simply open a browser from java code. But the second part of the problem states that its proxy settings must be set to a specific value. In order to achieve this we shall make use of Google Chrome's switches. A detailed description of the entire process is given below.

Google Chrome Switches : 

      The Chrome Browser allows the use of command line flags (or "switches") that the browser accepts in order to enable particular features or modify otherwise default functionality. To use these switches we need to modify the target of an application. This can be done as follows.

Step 1 : Create a shortcut of the chrome.exe file. (To create a shortcut right click on the chrome.exe application, go to the Send To submenu and click on Desktop(create shortcut) item. This will create a shortcut of the application on your desktop).

Step 2 : Right click on the shortcut and click on Properties.

Step 3 : Append the following flag to the target text box value --proxy-server=127.0.0.1:8080. Here 127.0.0.1, 8080 are the IP and port of the proxy server (You may change these to reflect your own proxy server). With this flag the target must now look like chrome.exe --proxy-server=127.0.0.1:8080. Note that there is a space between chrome.exe and the flag.

Step 4 : Click on Apply and close the Properties window.

      Now  if you open the shortcut it will start the browser with its proxy setting set. Note that if an instance of the chrome browser is already opened then the proxy settings wont be used, so you must close any running instances of the browser before opening the shortcut. These proxy settings will not be shown in the proxy settings accessible through the settings tab of chrome. So in order to verify you can set the proxy to any random free ip-port address and open the shortcut. If the proxy settings were indeed set, opening any website in the browser will show you the following error : Unable to connect to the proxy server. (for this check you may use 127.0.0.1:8080 as proxy settings provided you do not have a proxy set up on your machine).

      So if we are able to somehow open this shortcut from our java code we are set. We shall do exactly this with the exec method of the  Runtime class.


The Runtime class :

      The Runtime Class in java encapsulates the runtime environment. You can get a reference to the current Runtime object by calling the Runtime.getRuntime() method. Once a reference to the current runtime object is obtained we can call the exec method to execute a specific command. This command must open the shortcut of the browser that we had created earlier. The following command accomplishes this  :

cmd /c start /d \"d:\" chrome.lnk

      Note that here d: is the path of where our application is and chrome.lnk is the name of the application.  This means that I had kept the shortcut in my d: drive. So you can change the path to reflect the location of your shortcut file. (The name is chrome .lnk because the shortcuts in windows have the extension lnk).


The CODE!

Following is the complete code that does the above :

public class OpenBrowser {
   public static void main(String[] args) {
      try {
         Process process = Runtime.getRuntime().exec("cmd /c start /d \"d:\" chrome.lnk");
      }
      catch (Exception ex) {
         ex.printStackTrace();
      }
   }
}


Now the incorporation of the above method into an application where a click on a button triggers the above task is trivial.

Warning : Note that Google states the following on its chromium page
"It is important to note that using these switches is not supported or recommended. They should only be used for temporary cases and may break in the future."
So use this solution at your own risk :)
  

Saturday, 1 June 2013

Capture packets in Java using JPCAP (Ping packets)

      Java does not provide any inbuilt libraries for capturing IP packets. Hence we must rely on third party libraries for this task. JPCAP is one such library. JPCAP is an open source library for capturing and sending network packets from Java applications. It provides facilities to :

1. capture raw packets live from the wire.
2. save captured packets to an offline file, and read captured packets from an offline file.
3. automatically identify packet types and generate corresponding Java objects (for Ethernet, IPv4, IPv6, ARP/RARP, TCP, UDP, and ICMPv4 packets).
4. filter the packets according to user-specified rules before dispatching them to the application.
5. send raw packets to the network

      JPCAP makes use of native libraries for capturing packets. For Windows it uses WinPcap and for UNIX it relies on libpcap. As an example we shall capture the ping messages received by our machine. A small description of Ping is given below. 

Ping


      Ping is used to test the reachability of a host on an Internet Protocol (IP) network. It operates by sending Internet Control Message Protocol (ICMP) echo request packets to the target host and waiting for an ICMP echo reply messages. In the process it measures the time from transmission to reception (round-trip time) and records any packet loss.


Downloading dependencies & Setting up the environment



Downloads :


      Since JPCAP relies on WinPcap(for Windows)/libpcap(for UNIX), we must first download and install them. For Windows, WinPcap can be downloaded from the site http://www.winpcap.org. This must now be installed on your system. Also we need the JPCAP library, which can be downloaded from the link http://sourceforge.net/projects/jpcap/. If the links dont work simply search for them on google and choose the first links suggested.

Setup :


      For JPCAP to work you need to do the following two things :

1. Add jpcap.dll to the Java bin folder. The following steps accomplish this :
a.) Extract the downloaded JPCAP folder.
b.) Navigate to the lib folder inside the extracted folder. (i.e. navigate to jpcap-0.01.16-win32\lib. Note that the name of the downloaded folder may be different for a different version. It will however be of the form jpcap-...-win32). The lib folder must contain the jpcap.dll file.
c.) Copy the jpcap.dll file.
d.) Paste it in your jdk's bin folder. (Navigate to your Java folder. Open the jdk folder. Open the bin folder. Paste the file here)

2. Add the jpcap jar file to your classpath. The jpcap jar file is the file net.sourceforge.jpcap-0.01.16 included in the jars folder of the downloaded JPCAP folder. (If you are using Eclipse, you can do this by right clicking on the project, selecting Build Path, selecting add external archives and adding the required jar file).

The CODE!



PART 1 : To capture any packets we must use one of the network interfaces of our machine. To get the id of the network interface we use the following short java program.(Alternatively you can type ipconfig in the command prompt to get the device ID)

import net.sourceforge.jpcap.capture.CaptureDeviceNotFoundException;
import net.sourceforge.jpcap.capture.PacketCapture;
public class GetDeviceID {
    public static void main(String args[]){
        try {
           PacketCapture capture = new PacketCapture();
           String device=capture.findDevice();
           System.out.println(device);
        } catch (CaptureDeviceNotFoundException e) {
           // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

The above programs displays something like :

\Device\NPF_{04FGHGHA-D453-4450-945E-1145454557B4}
  Microsoft

Note down the part from the start of the string to the closing brace. This is the interface that we will listen to for packets.

PART 2 : Now we can capture the packets using the code given below.
The device ID being used is the one we found above. So replace the one shown below with your own. Note how the Device ID is specified in the call to capture.open().


import net.sourceforge.jpcap.capture.CaptureDeviceLookupException;
import net.sourceforge.jpcap.capture.PacketCapture;
import net.sourceforge.jpcap.capture.PacketListener;
import net.sourceforge.jpcap.net.ICMPMessages;
import net.sourceforge.jpcap.net.ICMPPacket;
import net.sourceforge.jpcap.net.Packet;

public class PingCapture {
    public static void main(String[] args) throws CaptureDeviceLookupException {
        Capture cap = new Capture();
        cap.doCapture();
    }
}

class PingListener implements PacketListener {
    @Override
    public void packetArrived(Packet packet) {
        try {
            // only ICMP packages
            if (packet instanceof ICMPPacket) {
                ICMPPacket tcpPacket = (ICMPPacket) packet;
                int data = tcpPacket.getMessageCode();
                // only echo request packages
                if (data == ICMPMessages.ECHO) {
                    // print source and destination.
                    String srcHost = tcpPacket.getSourceAddress();
                    String dstHost = tcpPacket.getDestinationAddress();
                    System.out.println("Ping from: " + srcHost + " to " + dstHost);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Capture {
    public void doCapture() {
        // create capture instance
        PacketCapture capture = new PacketCapture();
        // add listener that handles incoming and outgoing packages
        PingListener pingListener = new PingListener();
        capture.addPacketListener(pingListener);
        try {
            capture.open("\\Device\\NPF_{04FGHGHA-D453-4450-945E-1145454557B4}", true); // Replace the device ID with your own
            while (true) {
                capture.capture(1); // capture one packet, since this is in a loop, it will keep on capturing more packets
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            capture.removePacketListener(pingListener);
            capture.endCapture();
            capture.close();
        }
    }
}


      If everything went correctly, you will be able to see any ping requests received by you machine. If no ping messages are coming then nothing will be displayed. In this case to make sure whether the code is working, add a System.out.println() as the first statement of the packetArrived method. This will verify whether any packets are being received.

      Some common errors that may come up when you try to run the above code  are listed below:

Error 1: 
PacketCapture: loading native library jpcap.. Exception in thread "main" java.lang.UnsatisfiedLinkError: no jpcap in java.library.path
at java.lang.ClassLoader.loadLibrary(Unknown Source)
Solution: jpcap.dll file has not been copied to the java bin folder. See point #1 in the setup above to rectify this.


Error 2:
net.sourceforge.jpcap.capture.CaptureDeviceOpenException: Error opening adapter: The system cannot find the device specified. (20)
at net.sourceforge.jpcap.capture.PacketCapture.open(Native Method)
Solution: The device name is not correct. Replace the device specified in the above code to you own device ID. Note how the ID is specified(with two backslashes).


Error 3:
Getting errors during compilation of the form
error: package net.sourceforge.jpcap.capture does not exist
import net.sourceforge.jpcap.capture.CaptureDeviceLookupException;
Solution: Add the jpcap jar file to classpath. See point #2 in the setup above to rectify this.