/*(c) 2006 - 2008 AllenPort Co. All Rights Reserved.
All versions of this code, including the source and executable versions, 
constitute the intellectual property of AllenPort Co., which expressly reserves 
any and all U.S. and foreign rights and benefits to the code under copyright, 
trade secret and any other intellectual property law or international treaty 
whatsoever. Use of the code is subject to the terms and conditions of a separate 
written license agreement, and the code shall not be reproduced, modified, distributed 
or otherwise used in any form or manner whatsoever without obtaining the prior written 
permission of AllenPort Co. Any unauthorized reproduction or distribution of the code, 
or any portion of it, may result in civil and criminal penalties and be prosecuted 
to the fullest extent of the law.*/
/**
 * Encodes a string into the Base64 encoded notation.
 *
 * @param string the string to encode
 * @return string the encoded string
 * @author www.farfarfar.com
 * @version 0.1
 */

function base64Encode(str)
{
	var charBase64 = new Array(
		'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
		'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
		'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
		'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
	);

	var out = "";
	var chr1, chr2, chr3;
	var enc1, enc2, enc3, enc4;
	var i = 0;

	var len = str.length;

	do
	{
		chr1 = str.charCodeAt(i++);
		chr2 = str.charCodeAt(i++);
		chr3 = str.charCodeAt(i++);

		//enc1 = (chr1 & 0xFC) >> 2;
		enc1 = chr1 >> 2;
		enc2 = ((chr1 & 0x03) << 4) | (chr2 >> 4);
		enc3 = ((chr2 & 0x0F) << 2) | (chr3 >> 6);
		enc4 = chr3 & 0x3F;

		out += charBase64[enc1] + charBase64[enc2];

		if (isNaN(chr2))
  		{
			out += '==';
		}
  		else if (isNaN(chr3))
  		{
			out += charBase64[enc3] + '=';
		}
		else
		{
			out += charBase64[enc3] + charBase64[enc4];
		}
	}
	while (i < len);

	return out;
}

/**
 * Decodes a string from the Base64 encoded notation.
 *
 * @param string the string to decode
 * @return string the decoded string
 * @version 0.1
 */

function base64Decode(str)
{
	var indexBase64 = new Array(
		-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
		-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
		-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
		52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
		-1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
		15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
		-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
		41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1,
		-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
		-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
		-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
		-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
		-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
		-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
		-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
		-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
	);

	var out = "";
	var chr1, chr2, chr3;
	var enc1, enc2, enc3, enc4;
	var i = 0;

	// trim invalid characters in the beginning and in the end of the string

	str = str.replace(/^[^a-zA-Z0-9\+\/\=]+|[^a-zA-Z0-9\+\/\=]+$/g,"")

	var len = str.length;

	do
	{
		enc1 = indexBase64[str.charCodeAt(i++)];
		enc2 = indexBase64[str.charCodeAt(i++)];
		enc3 = indexBase64[str.charCodeAt(i++)];
		enc4 = indexBase64[str.charCodeAt(i++)];

		chr1 = (enc1 << 2) | (enc2 >> 4);
		chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
		chr3 = ((enc3 & 3) << 6) | enc4;

		out += String.fromCharCode(chr1);

		if (enc3 != -1)
		{
			out += String.fromCharCode(chr2);
		}
		if (enc4 != -1)
		{
			out += String.fromCharCode(chr3);
		}
	}
	while (i < len);

	if (i != len)
	{
		new Error(BASE64_BROKEN);
		return "";
	}

	return out;
}

/**
 * Unencodes a hex-encoded string to a binary string
 * @param str the string to unencode
 * @return string the unencoded string
 */

function base64ToOpenSSl(str)
{
    var base64_enc = base64Encode(str);
    var out = "";
    var block_size = 64;
    
    for(var i = 0; i < base64_enc.length; i+=block_size)
        out += base64_enc.substr(i, block_size) + '\n';
    
    return out;
}

function openSSLToBase64(str)
{
    var base_correct = str.split('\n').join('');
    return base64Decode(base_correct);
}

var HEX_BROKEN = "Invalid hex encoded text";
var BASE64_BROKEN = "Possibly invalid Base64 encoded text";

var errors = new Array();
var errorLen = 0;

function Error(error)
{
	alert(error);
}

function hexToStr(str)
{
	var charHex = new Array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f');
	var stringHex = "0123456789abcdef";
	
	var out = "";
	var len = str.length;
	str = new String(str);
	str = str.toLowerCase();
	if ((len % 2) == 1)
	{
		str += "0";
	}
	for (var i = 0; i < len; i+=2)
	{
	    var s1 = str.substr(i, 1);
	    var s2 = str.substr(i+1, 1);
		var index1 = stringHex.indexOf(s1);
		var index2 = stringHex.indexOf(s2);
		
		if (index1 == -1 || index2 == -1)
		{
			new Error(HEX_BROKEN);
			return "";
		}
		
		var val = (index1 << 4) | index2;
		
	    out += "" + String.fromCharCode(parseInt(val));
	}
	return out;
}

/**
 * Encodes a string string to a hex-encoded string
 * @param str the string to unencode
 * @return string the unencoded string
 */

function strToHex(str)
{
	var charHex = new Array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f');
	
	var out = "";
	var len = str.length;
	str = new String(str);
	for (var i = 0; i < len; i++)
	{
	    var s = str.charCodeAt(i);
	    var h = "" + charHex[s >> 4] + "" + charHex[0xf & s];
	    
	    out += "" + h;
	}
	return out;
}