public static final String md5hash(String cleartext)
  {
    try
    {
      MessageDigest md = MessageDigest.getInstance("MD5");
      byte[] digest = md.digest(cleartext.getBytes());
      StringBuffer sb = new StringBuffer();
      for (int i = 0; i < digest.length; i++)
      {
        int hiNybble = digest[i] >> (byte) 0x04;
        int loNybble = digest[i] & (byte) 0x0F;
        sb.append(nybbleToUnsignedNybbleString(hiNybble));
        sb.append(nybbleToUnsignedNybbleString(loNybble));
        sb.append(":");
      }
      sb.deleteCharAt(sb.length() - 1);
      return sb.toString();
    }
    catch (NoSuchAlgorithmException nsae)
    {
      System.err.println("Couldn't get MD5 MessageDigest
        instance: " + nsae);
      nsae.printStackTrace(System.err);
      return null;
    }

    }

    public static final String nybbleToUnsignedNybbleString(int
      nybble)
    {
      int value = 0;
      if ((nybble & 0x01) != 0) value += 1;
      if ((nybble & 0x02) != 0) value += 2;
      if ((nybble & 0x04) != 0) value += 4;
      if ((nybble & 0x08) != 0) value += 8;
      return Integer.toString(value, 16);
    }
