Seeding the random number generator

You can set the seed of the Random class manually:

   Random r = new Random(10);
   
   or
  
   Random r = new Random();
   r.setSeed(10);

ie:

import java.util.*;
 
public class Main 
{  
   public static void main(String args[]) {
      Random r = new Random(10);
      for (int i=0; i<10; i++) {
         float f = r.nextFloat();
         System.out.println(f);
      }
   }
}

outputs:

0.73043025
0.44563425
0.25780278
0.41291267
0.059201956
0.67215943
0.2441172
0.36817038
0.818809
0.3567646

Running the app another time will yield the same pseudo-random numbers.

Downloading a remote file in Java

Create an instance of the URL class, open the TCP stream and read the data
from the inputstream provided by the URL object.
Following code demonstrates this:

import java.net.*;
import java.io.*;
  
public class Main
{
   public static void main(String args[]) 
   {
      try {
         if (args.length != 1) {
            System.err.println("Usage: java Main <URL>");
            System.exit(0);
         }
 
         URL url = new URL(args[0]);
         InputStream in = url.openStream();
 
         BufferedReader br = new BufferedReader(new InputStreamReader(in));
  
         String line;
         while ((line = br.readLine()) != null) {
            System.out.println(line);
         }
      }
      catch (MalformedURLException e) {
         System.err.println (e);
      }
      catch (IOException e) {
         System.err.println (e);
      }
   }
}

prints the following to standard output:

<html>
<body>
<h1> HELLO WORLD! </h1>
</body>
</html>

Getting the file size of a URL file

You could use the HTTP header field content-length as follows:

import java.net.*;
import java.io.*;
 
public class Main {
   public static final void main(String[] args) {
      if (args.length != 1) {
         System.out.println("Usage: java Main <URL>");
         System.exit(1);
      }
 
      try {
         URL url = new URL(args[0]);
         URLConnection connection = url.openConnection();
         int size = connection.getContentLength();
         if (size > -1) {
            System.out.println("Content length is " + size);
         }
         else {
            System.out.println("Content length is not known");
         }
      }
      catch(Exception e) {
         System.err.println(e);
      }
   }
}

outputs with (java Main http://www.esus.com):

Content length is 43041

(I really should start trimming it down :)

Beware that this length does not include the embedded images or other embedded objects.

Also note that a lot of times, especially with dynamically generated pages, getContentLength returns -1 meaning it could not determine the size. In that case you should count the number of bytes as you download the URL through one of the InputStreams or Readers.

Simple example of a DatagramClient and DatagramServer

SenderGram.java:

/*
Program developed by Juleat K.R(Apech Computer education, fortkochi and 
Vinodvalittoor, Aptech Tirur. complaints and compliments send to 
julis_in@yahoo.com or vinwin01@yahoo.com
Thank you..

send datagram....................................... */
 
import java.net.*;
 
public class SenderGram
{
   public static void main(String ar[])
   {
      try {
         if (ar.length != 1) {
            System.err.println("Usage: java SenderGram <message>");
            System.exit(1);
         }
 
         InetAddress ia=InetAddress.getByName("LocalHost");
         int port=Integer.parseInt("2495");
 
         DatagramSocket ds=new DatagramSocket();
         byte buffer[]=ar[0].getBytes();
 
         DatagramPacket dp=new DatagramPacket(buffer,buffer.length,ia,port);
 
         ds.send(dp);
      }
      catch(Exception e) {
         e.printStackTrace();
      }
   }
}

ReceiverGram.java:

/* recieve datagram.................................... */
 
import java.net.*;
 
public class ReceiverGram
{
   public final static int BUFSIZE=20;
 
   public static void main(String ar[])
   {
      try {
         int port=Integer.parseInt("2495");
         DatagramSocket ds=new DatagramSocket(port);
         byte buffer[]=new byte[BUFSIZE];
 
         while (true) {
            DatagramPacket dp=new DatagramPacket(buffer,buffer.length);
            ds.receive(dp);
            String str=new String(dp.getData());
            System.out.println(str);
         } 
      }
      catch(Exception e) {
         System.err.println(e);
      }
   }
}

What is non-repudiation?

Non-repuditation means the ability to prove that a transaction originated from a particular party. So that party cannot deny that he performed a certain transaction. A receiver cannot deny that he received a certain message from a sender, and a sender cannot deny that he sent a message to the receiver.

What is symmetric cryptography?

In Symmetric Cryptography (also: secret key cryptography), an algorithm is used to scramble the message using a secret key in such a way that it becomes unusable to all except the ones that have access to that secret key. The most widely known symmetric cryptographic algorithm is DES, developed by IBM in the 70ies. It uses a key of 56 bits and operates on chunks of 64 bits at a time. The problem with DES is the short key length, making it possible for someone, that doesn’t have access to the private key, to try all possible keys. DESede provides a significant improvement with the key being 3 times as large.

Symmetric cryptography works very well if encryption and decryption are eventually performed by the same party. But if there are 2 or more parties involved, there is the question of how to exchange the secret key without anyone spying. Look at asymettric cryptography for a solution.

What is hybrid cryptography?

Symmetric and asymmetric ciphers each have their own advantages and disadvantages. Symmetric ciphers are significantly faster (Schneier states “at least 1000 times faster”) than asymmetric ciphers, but require all parties to somehow share a secret (the key). The asymmetric algorithms allow public key infrastructures and key exchange systems, but at the cost of speed.

A hybrid cryptosystem is a protocol using multiple ciphers of different types together, each to it’s best advantage. One common approach is to generate a random secret key for a symmetric cipher, and then encrypt this key via an asymmentric cipher using the recipient’s public key. The message itself is then encrypted using the symmetric cipher and the secret key. Both the encrypted secret key and the encrypted message are then sent to the recipient.

The recipient decrypts the secret key first, using his/her own private key, and then uses that key to decrypt the message. This is basically the approach used in PGP.

Using the class MessageFormat

MessageFormat is a useful class to format dynamic messages that depend on a number of variables. In other words, it allows you to replace certain parts of a String template.

For example, consider the following example template: (letter.txt)


				{0}, {1,date},
 
 
Dear {2}, 
 
	I regret to inform you that you have been eliminated from 
further contention to become the future Mrs. {3}. As you are 
probably aware, the competition was exceedingly tough this year and 
{4,number,integer} well-qualified canditates such as yourself also failed to 
make the final cut. I will, however, keep your name on file should 
an opening come available or I become extremely horny. 
  
					 Sincerely, 
 
					 {5} {3}

To be able to send this letter to many persons, we have created a template in which all things that are likely to vary are replaced by number of var, [type, [format of type]] enclosed in curly braces ({}). In our example, we’d like to replace {0} by the location, {1} by the date of today, {2} by the potential girlfriend that is about to be rejected :), {3} by the name of the person, {4} by the number of applicants, {5} by our first name and {3} by our last name.

Performing the replacement is simple, just instantiate an object of MessageFormat and initialize it with this text. Then call the method format and pass it an array in which the object at the index of the array refers to the variable with the same number.

      String letter = ... (initialize to above text) ...
 
      MessageFormat mf = new MessageFormat(letter);
 
      Object[] vars = { "Brussels",         // {0}
                        new Date(),         // {1, date}
                        "Ulla",             // {2}
                        "Doe",              // {3}
                        new Integer(12),    // {4, number, integer}
                        "John" };           // {5}
      String formattedLetter = mf.format(vars);

The result (formattedLetter) will be:

 
				Brussels, Jun 25, 2001,
 
 
Dear Ulla, 
 
	I regret to inform you that you have been eliminated from 
further contention to become the future Mrs. Doe. As you are 
probably aware, the competition was exceedingly tough this year and 
12 well-qualified canditates such as yourself also failed to 
make the final cut. I will, however, keep your name on file should 
an opening come available or I become extremely horny. 
  
					 Sincerely, 
 
					 John Doe

Here’s the complete program:

import java.text.*;
import java.util.*;
import java.io.*;
  
public class Main {
   public static void main(String []args) throws Exception {
      if (args.length != 1) {
         System.err.println("Usage: java Main <letter.txt>");
         System.exit(1);
      }
 
      String letter = readFile(args[0]);
      MessageFormat mf = new MessageFormat(letter);
 
      Object[] vars = { "Brussels",
                        new Date(),
                        "Ulla",
                        "Doe",
                        new Integer(12),
                        "John" };
      String formattedLetter = mf.format(vars);
 
      System.out.println(formattedLetter);
   }
 
   public static String readFile(String filename) throws Exception {
      BufferedReader br = new BufferedReader(new FileReader(filename));
      StringBuffer buffer = new StringBuffer();
 
      String ls = System.getProperty("line.separator");
      String line;
      while ((line = br.readLine()) != null) {
         buffer.append(line + ls);
      }
 
      return buffer.toString();
   }
}

You shouldn’t use MessageFormat as a report generator though. For one thing, you can use maximum 10 variables (from {0} to {9}) inside your template. Check out this entry in Sun’s bug parade to evaluate whether it is a bug or not.

Instead, use it for relatively small messages that need to be customized or internationalized, like localized error or status messages. Also, you don’t have to create a instance of MessageFormat; you can use its static method format. It looks much like the C function sprintf.

Main.java:

import java.text.*;
import java.util.*;
import java.io.*;
  
public class Main {
   public static void main(String []a) throws Exception {
      String s = MessageFormat.format("Price is {0,number,$##.#}, VAT included.", 
                                      new Object[] { new Float(8.46) });
      System.out.println(s);
   }
}

outputs:

Price is $8.5, VAT included.

MessageFormat and ChoiceFormat

For example, suppose we want to create a message to the user to show him information about the amount of new emails he’s got. We could have the following possibilities:

   You have no emails.    		[ if #emails == 0 ]
   You have one email.    		[ if #emails == 1 ]
   You have a couple of emails.    	[ if #emails > 1 and < 8 ]
   You have X emails.			[ if #emails >= 8 ]

There are two substrings that vary here depending on #emails:

   You have [VAR] email[VAR]

VAR2 is necessary to account for the missing “s” in the second case. This leads to the introduction of a class called ChoiceFormat, which is typically used in conjunction with MessageFormat to solve these types of problems. It allows you to “connect” an numeric interval to a result as a String. So, we want:

   "no"  		if #emails == 0
   "one"		if #emails == 1
   "a couple of"	if #emails in range [1, 8[
   #emails		if #emails in range [8, ...

Converting this to a ChoiceFormat:

#1   double[] limits0 = {0, 1, 2, 8};
#2   String[] choices0 = { "no", "one", "a couple", "{0, number}" };
 
#3   ChoiceFormat format0 = new ChoiceFormat(limits0, choices0);
#4   mf.setFormat(0, format0); 

Line number #1 encodes the intervals. According to the API, choices0[j] will be chosen if and only if limits0[j] < = #emails < limit[j+1]. Line number #4 tells the MessageFormat instance to use this ChoiceFormat when formatting the first variable (0 in this case means the first variable it encounters in the template “You have [VAR] email[VAR]“).

To format the second variable (“You have [VAR] email[VAR]“), we use the same technique:

   "s"		if #emails = 0
   ""		if #emails = 1
   "s"		if #emails > 1

Converting this to a ChoiceFormat:

#1    double[] limits1 = {0, 1, 2};
#2    String[] choices1 = { "s", "", "s" };
 
#3    ChoiceFormat format1 = new ChoiceFormat(limits1, choices1);
#4    mf.setFormat(1, format1);

Here’s the complete program: (Main.java)

import java.text.*;
import java.util.*;
import java.io.*;
  
public class Main {
   public static void main(String []args) throws Exception {
      MessageFormat mf = new MessageFormat("You have {0} email{0}.");
 
      double[] limits0 = {0, 1, 2, 8};
      String[] choices0 = { "no", "one", "a couple", "{0, number}" };
      ChoiceFormat format0 = new ChoiceFormat(limits0, choices0);
      mf.setFormat(0, format0);
 
      double[] limits1 = {0, 1, 2};
      String[] choices1 = { "s", "", "s" };
      ChoiceFormat format1 = new ChoiceFormat(limits1, choices1);
      mf.setFormat(1, format1);
 
      String message = mf.format(new Object[] {new Integer(0)});
      System.out.println(message);
 
      message = mf.format(new Object[] {new Integer(1)});
      System.out.println(message);
 
      message = mf.format(new Object[] {new Integer(7)});
      System.out.println(message);
 
      message = mf.format(new Object[] {new Integer(23)});
      System.out.println(message);
   }
}

outputs:

You have no emails.
You have one email.
You have a couple emails.
You have 23 emails.

Of course, you could also incorporate ResourceBundles as shown in following example.

LabelResourceBundle_en.java:

import java.util.*;
 
public class LabelResourceBundle_en extends ListResourceBundle
{
   private Object[][] contents = 
      { { "greeting", 		"Hello" } };
  
   public Object[][] getContents() {
      return contents;
   }
}

LabelResourceBundle_fr_BE.java:

import java.util.*;
 
public class LabelResourceBundle_fr_BE extends ListResourceBundle
{
   private Object[][] contents = 
      { { "greeting", 		"Bonjour" } };
  
   public Object[][] getContents() {
      return contents;
   }
}

Main.java:

import java.text.*;
import java.util.*;
import java.io.*;
  
public class Main {
   public static void main(String []a) throws Exception {
      ResourceBundle rb = ResourceBundle.getBundle("LabelResourceBundle");
 
      MessageFormat mf = new MessageFormat("{0}, {1}");
 
      // use default locale
      Object[] args = new Object[] { rb.getString("greeting"), "John Doe" };
      System.out.println(mf.format(args));
 
      // change locale
      rb = ResourceBundle.getBundle("LabelResourceBundle", new Locale("fr", "BE"));
      args = new Object[] { rb.getString("greeting"), "John Doe" };
      System.out.println(mf.format(args));
   }
}

outputs:

Hello, John Doe
Bonjour, John Doe

What is a locale?

A locale identifies a particular language and region. Optionally, you can specify a custom parameter called a variant. A locale object is useful for internationalization. For example: in the US the decimal symbol is point whereas in Belgium it’s a comma. To format the number correctly to the user, your application must consult the Locale object to determine the current language or region.

Whenever you create a locale object without specifying language or region, you’ll get the default one. This one is automatically determined as follows:

   System.getProperty("user.language");  // for language
   System.getProperty("user.region");    // for region

To get the default locale:

   Locale locale = Locale.getDefault();

You can create your own locale object as follows:

   Locale locale = new Locale("nl", "BE");

Optionally, you can specify a variant:

   Locale locale = new Locale("fr", "BE", "LINUX");

Classes that depend on a language (NumberFormat, DateFormat, …) or region are called locale-sensitive. Typically, you can call the static method getAvailableLocales on that class to find out the locales that work with that class. A resource bundle (see the category resourcebundles) also makes heavily use on locales, as it needs them to determine the correct class name or properties file.

Once you have a particular locale identified through one of the constructors, you have access to several methods to find out more about that locale. Look at the API for more information. Here’s an example:

import java.util.*;
 
public class Main {
   public static void main(String []args) {
      Locale locale = Locale.getDefault(); 
 
      System.out.println("Language         " + locale.getLanguage());
      System.out.println("Country          " + locale.getCountry());
      System.out.println("Variant          " + locale.getVariant());
      System.out.println("DisplayLanguage  " + locale.getDisplayLanguage());
      System.out.println("DisplayCountry   " + locale.getDisplayCountry());
      System.out.println("DisplayVariant   " + locale.getDisplayVariant());
      System.out.println("DisplayName      " + locale.getDisplayName());
      System.out.println("ISO3Country      " + locale.getISO3Country());
      System.out.println("ISO3Language     " + locale.getISO3Language());
   }
}

outputs:

Language         en
Country          US
Variant          
DisplayLanguage  English
DisplayCountry   United States
DisplayVariant   
DisplayName      English (United States)
ISO3Country      USA
ISO3Language     eng