/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.security;

import java.security.MessageDigest;

public class PasswordHash
{
  /*--------------------------------------------------------------------------------
   * Attributes
   *--------------------------------------------------------------------------------
   */

  private String value;    // the hashed password value

  /*--------------------------------------------------------------------------------
   * Constructors
   *--------------------------------------------------------------------------------
   */

  public PasswordHash()
  {
    value = "";

  } // end constructor

  public PasswordHash(String password)
  {
    if ((password!=null) && (password.length()>0))
    { // hash the password and save the hash value
      MessageDigest hasher;

      try
      { // get a hasher implementing the Secure Hashing Algorithm
	hasher = MessageDigest.getInstance("SHA");

      } // end try
      catch (java.security.NoSuchAlgorithmException e)
      { // SHA should be a standard algorithm...if it isn't, we're h0sed
	throw new RuntimeException("HOSED JRE - SHA should be a standard algorithm");

      } // end catch

      try
      { // update the hasher with the UTF-8 bytes of the password
	hasher.update(password.getBytes("UTF8"));

      } // end try
      catch (java.io.UnsupportedEncodingException e)
      { // WTF? How can the JRE NOT know about UTF-8?  HOW?!?
	throw new RuntimeException("HOSED JRE - UTF-8 encoding should be supported");

      } // end catch

      // Retrieve the raw hash value (should be 160 bits, or 20 bytes)
      byte[] raw_hash = hasher.digest();

      // Convert the hash value to a hexadecimal string (40 chars in length)
      StringBuffer hash_buf = new StringBuffer(raw_hash.length * 2);
      StringBuffer tmp_buf = new StringBuffer();
      String tmp;
      for (int i=0; i<raw_hash.length; i++)
      { // N.B.: Integer.toHexString does not zero-pad on the left, so that's why this is
	// a little complex
	tmp_buf.setLength(0);
	tmp_buf.append("00").append(Integer.toHexString(raw_hash[i]).trim());
	tmp = tmp_buf.toString();
	hash_buf.append(tmp.substring(tmp.length()-2));

      } // end for

      // finally, save off the password hash value
      value = hash_buf.toString().toUpperCase();

    } // end if
    else  // no password
      value = "";

  } // end constructor

  /*--------------------------------------------------------------------------------
   * Overrides from class Object
   *--------------------------------------------------------------------------------
   */

  public String toString()
  {
    return value;

  } // end toString

  public boolean equals(Object obj)
  {
    if (obj==null)
      return false;  // trivial case
    else if (obj==(Object)this)
      return true;   // trivial case
    if (obj instanceof PasswordHash)
    { // compare value of PasswordHash argument to value
      PasswordHash other = (PasswordHash)obj;
      return value.equals(other.value);

    } // end if
    else
      return value.equals(obj.toString());

  } // end equals

  public int hashCode()
  {
    return value.hashCode();

  } // end hashCode

  /*--------------------------------------------------------------------------------
   * Test program
   *--------------------------------------------------------------------------------
   */

  public static void main(String[] args)
  {
    if (args.length<1)
    { // no password specified
      System.err.println("usage: PasswordHash password");
      System.exit(1);

    } // end if

    PasswordHash foo = new PasswordHash(args[0]);
    System.out.println(foo.toString());
    System.exit(0);

  } // end main
  
} // end class PasswordHash
