function fnSalt()  {
	var cChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	var nPos
	var cSalt = ""
	for (var i=0;i<8;i++) {
		nPos = Math.floor(cChars.length*Math.random())
		cSalt = cSalt + cChars.substr(nPos,1)
	}
	return cSalt
}

/***************************************************************************
 * SecureHash(s): Calculates the message digest for the given string using *
 * the SHA-1 algorithm.                                                    *
 **************************************************************************/

function fnHash(s) {

  var bitLen, n, w;
  var k, aBuffer, f;
  var h0, h1, h2, h3, h4;
  var a, b, c, d, e, temp;
  var i, j;

  // Pad the input message per the SHA-1 specification.

  bitLen = s.length * 8;
  n = 512 - (bitLen % 512);
  if (n <= 65)
	 n += 512;
  s += String.fromCharCode(0x80);
  n -= 8;
  for (i = 0; i < n / 8; i++)
	 s += String.fromCharCode(0x00);

  // Convert padded message to an array of 32-bit integers, note conversion
  // to little endian.

  w = new Array();
  for (i = 0; i < s.length; i += 4) {
	 n = 0;
	 for (j = 0; j < 4; j++)
		n = (n << 8) + s.charCodeAt(i + j);
	 w[w.length] = n;
  }

  // Set last word to the original bit length of the message.

  w[w.length - 1] = bitLen;

  // Initialize hash values, constants and aBuffer.

  h0 = 0x67452301;
  h1 = 0xEFCDAB89;
  h2 = 0x98BADCFE;
  h3 = 0x10325476;
  h4 = 0xC3D2E1F0;

  k = new Array(80);
  for (i = 0; i < 80; i++)
	if (i < 20)
	  k[i] = 0x5A827999;
	else if (i < 40)
	  k[i] = 0x6ED9EBA1;
	else if (i < 60)
	  k[i] = 0x8F1BBCDC;
	else
	  k[i] = 0xCA62C1D6;

  aBuffer = new Array(80);

  // Process word array in 512-bit (16-word) blocks.

  n = w.length / 16;
  for (i = 0; i < n; i ++) {

	 // Initialize 80-word aBuffer using the current block.

	 for (j = 0; j < 80; j++)
		if (j < 16)
		  aBuffer[j] = w[i * 16 + j];
		else
		  aBuffer[j] = fnHashRol(aBuffer[j - 3] ^ aBuffer[j - 8] ^ aBuffer[j - 14] ^
								aBuffer[j - 16], 1);

	 a = h0; b = h1; c = h2; d = h3; e = h4;

	 // Hash the block.

	 for (j = 0; j < 80; j++) {
		temp = fnHashRol(a, 5);
		if (j < 20)
		  f = (b & c) | ((~b) & d);
		else if (j < 40)
		  f = b ^ c ^ d;
		else if (j < 60)
		  f = (b & c) | (b & d) | (c & d);
		else
		  f = b ^ c ^ d;
		temp = fnHashAdd(temp, f);
		temp = fnHashAdd(temp, e);
		temp = fnHashAdd(temp, aBuffer[j]);
		temp = fnHashAdd(temp, k[j]);
		e = d; d = c; c = fnHashRol(b, 30); b = a; a = temp;
	 }

	 // Update hash values.

	 h0 = fnHashAdd(h0, a);
	 h1 = fnHashAdd(h1, b);
	 h2 = fnHashAdd(h2, c);
	 h3 = fnHashAdd(h3, d);
	 h4 = fnHashAdd(h4, e);
  }

  // Format hash values and return as message digest.

  return fnHashHex(h0) + fnHashHex(h1) + fnHashHex(h2) + fnHashHex(h3) + fnHashHex(h4);
}

// Helper functions for the Secure Hash function.

function fnHashRol(x, n) {

  // Left circular shift for a 32-bit integer.

  return (x << n) | (x >>> (32 - n));
}

function fnHashAdd(x, y) {

  // Add two 32-bit integers, wrapping at 2^32.

  return ((x & 0x7FFFFFFF) + (y & 0x7FFFFFFF)) ^
			 (x & 0x80000000) ^ (y & 0x80000000)
}

function fnHashHex(n) {

  var hexDigits = "0123456789ABCDEF";
  var i, s;

  // Format a 32-bit integer as a hexadecimal string.

  s = "";
  for (i = 7; i >= 0; i--)
	 s += hexDigits.charAt((n >> (i * 4)) & 0x0F);

  return s;
}

