/* Secure Hash Algorithm (SHA-1) */

var k = new Array(3)
k[0] = SHA1_Add(0, 0x5a827999)
k[1] = SHA1_Add(0, 0x6ed9eba1)
k[2] = SHA1_Add(0, 0x8f1bbcdc)
k[3] = SHA1_Add(0, 0xca62c1d6)

var StrHexCharacters = "0123456789abcdef" 

function SHA1_Hash(pStrMessage)
{
	var W = new Array(80)

	var M = SHA1_MakeBlocks(pStrMessage)

	var A = SHA1_Add(0, 0x67452301)
	var B = SHA1_Add(0, 0xefcdab89)
	var C = SHA1_Add(0, 0x98badcfe)
	var D = SHA1_Add(0, 0x10325476)
	var E = SHA1_Add(0, 0xc3d2e1f0)

	var a = A
	var b = B
	var c = C
	var d = D
	var e = E
	
	for(var i = 0; i < M.length; i += 16)
	{
		for(var t = 0; t < 80; t++)
		{
			if(t < 16)
			{
				W[t] = M[i + t]
			}
			else
			{
				W[t] = SHA1_LeftCircularShift(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1)
			}

			temp = SHA1_Add(SHA1_Add(SHA1_LeftCircularShift(a, 5), SHA_f(t, b, c, d)), SHA1_Add(SHA1_Add(e, W[t]), SHA_K(t)))

			e = d
			d = c
			c = SHA1_LeftCircularShift(b, 30)
			b = a
			a = temp
		}

		A = SHA1_Add(a, A)
		B = SHA1_Add(b, B)
		C = SHA1_Add(c, C)
		D = SHA1_Add(d, D)
		E = SHA1_Add(e, E)
	}

	return(SHA1_Hex(A) + SHA1_Hex(B) + SHA1_Hex(C) + SHA1_Hex(D) + SHA1_Hex(E))
}

function SHA1_Hex(pLngValue)
{
	var lStrHex = ''
	var lLngPositionIndex
	for(var lLngPositionIndex = 7; lLngPositionIndex >= 0; lLngPositionIndex--)
	{
		lStrHex += StrHexCharacters.charAt((pLngValue >> (lLngPositionIndex * 4)) & 0x0f)
	}
	return(lStrHex)
}

function SHA1_MakeBlocks(pStrMessage)
{
	var lLngMaxBlock = ((pStrMessage.length + 8) >> 6) + 1
	var lStrBlockAry = new Array(lLngMaxBlock * 16)
	var lLngIndex

	for(lLngIndex = 0; lLngIndex < lLngMaxBlock * 16; lLngIndex++)
	{
		lStrBlockAry[lLngIndex] = 0
	}

	for(lLngIndex = 0; lLngIndex < pStrMessage.length; lLngIndex++)
	{
		lStrBlockAry[lLngIndex >> 2] |= pStrMessage.charCodeAt(lLngIndex) << (24 - (lLngIndex % 4) * 8)
	}

	lStrBlockAry[lLngIndex >> 2] |= 0x80 << (24 - (lLngIndex % 4) * 8)
	lStrBlockAry[lLngMaxBlock * 16 - 1] = pStrMessage.length * 8

	return(lStrBlockAry)
}

function SHA1_Add(pLngValue1, pLngValue2)
{
	var lLngA = (pLngValue1 & 0xFFFF) + (pLngValue2 & 0xFFFF)
	var lLngB = (pLngValue1 >> 16) + (pLngValue2 >> 16) + (lLngA >> 16)
	var lLngResult = (lLngB << 16) | (lLngA & 0xFFFF)
	return(lLngResult)
}

function SHA1_LeftCircularShift(pLngValue, pLngBits)
{
	return(pLngValue << pLngBits) | (pLngValue >>> (32 - pLngBits))
}

function SHA_f(t, x, y, z)
{
	if(t < 20) return((x & y) | ((~x) & z))
	if(t < 40) return(x ^ y ^ z)
	if(t < 60) return((x & y) | (x & z) | (y & z))
	return x ^ y ^ z

}

function SHA_K(t)
{
	if(t < 20) return(k[0])
	if(t < 40) return(k[1])
	if(t < 60) return(k[2])
	return(k[3])
}

