/*
	Skeleton high-performance crypt lib for NPL.
*/

//	Handle Base64 encoding.
//	Generate a general-purpose array of the characters used for Base64 encoding.
var gB64Chars = (function(pChars){return pChars.split('')})('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=');

//	Generate a Javascript-style hash map that resolves Base64 characters to their integer value.
var gB64Indexes = (function(){var x={}; var n=gB64Chars.length; for (var i=0; i<n; i++){x[gB64Chars[i]]=i}; return x;})();

B64Encode = function (pString)
{
	/*
		Quickly Base64-encode a string.
	*/
	var j, xSum, pad = '';
	var xReturnValue = [];
	//	First pad pString to a multiple of 3.
	switch ( pString.length % 3 )
	{
		case 1:
			pString += "\0\0";
			pad = '==';
			break;
		case 2:
			pString += "\0";
			pad = '=';
	}
	for ( var i = j = 0; i < pString.length; i++ )
	{
		//	Get the values of the 3 normal chars and sum them together.
		xSum = pString.charCodeAt(i++)<<16 | pString.charCodeAt(i++)<<8 | pString.charCodeAt(i);
		//	Split the sum apart into the base64 chars that represent it.
		xReturnValue[j++] = gB64Chars[xSum>>18 & 0x3f] + gB64Chars[xSum>>12 & 0x3f] + gB64Chars[xSum>>6 & 0x3f] + gB64Chars[xSum & 0x3f];
	}
	//	Fix up the padding on the end and return the result.
	return pad == '' ? xReturnValue.join('') : xReturnValue.join('').slice(0, -1 * pad.length) + pad;
};
				
B64Decode = function (pString)
{
	/*
		Quickly decode a Base64-encoded string.
	*/
	var h, j, bits;
	var xReturnValue = [];
	var c = String.fromCharCode;
	for ( var i = j = 0; i < pString.length; i++ )
	{
		//	Get the values of the 4 base64 chars.
		h = [gB64Indexes[pString.charAt(i++)], gB64Indexes[pString.charAt(i++)], gB64Indexes[pString.charAt(i++)], gB64Indexes[pString.charAt(i)]];
		//	Get their sum.
		bits = h[0]<<18 | h[1]<<12 | h[2]<<6 | h[3];
		//	Split the sum apart into the 1, 2, or 3 real characters that it represents.
		xReturnValue[j++] = h[3] == 64 ? h[2] == 64 ? c(bits>>>16 & 0xff) : c(bits>>>16 & 0xff, bits>>>8 & 0xff) : c(bits>>>16 & 0xff, bits>>>8 & 0xff, bits & 0xff);
	}
	return xReturnValue.join('');
};

