/***
**
** Constructeur
**
***/
function Codec()
{
	this.sBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	this.iBase64 = 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
 							);
}

/***
**
** Encodage
**
***/
Codec.prototype.encode =
function(decStr)
{
	 var bits, dual, i = 0, encOut = "";
	 while(decStr.length >= i + 3) {
		 bits =
			 (decStr.charCodeAt(i++) & 0xff) <<16 |
			 (decStr.charCodeAt(i++) & 0xff) <<8 |
			 decStr.charCodeAt(i++) & 0xff;
			 
			 encOut +=
			 this.sBase64.charAt((bits & 0x00fc0000) >>18) +
			 this.sBase64.charAt((bits & 0x0003f000) >>12) +
			 this.sBase64.charAt((bits & 0x00000fc0) >> 6) +
			 this.sBase64.charAt((bits & 0x0000003f));
	 }
	 if(decStr.length - i > 0 && decStr.length - i < 3) {
		 dual = Boolean(decStr.length - i - 1);
		 bits =
			 ((decStr.charCodeAt(i++) & 0xff) <<16) |
			 (dual ? (decStr.charCodeAt(i) & 0xff) <<8 : 0);
		 encOut +=
			 this.sBase64.charAt((bits & 0x00fc0000) >>18) +
			 this.sBase64.charAt((bits & 0x0003f000) >>12) +
			 (dual ? this.sBase64.charAt((bits & 0x00000fc0) >>6) : '%3D') +
			 '%3D';
	 }
	 return(encOut);
}

/***
**
** Decodage
**
***/
Codec.prototype.decode =
function(encStr)
{
	// variables correspondant aux octets du caractere de sortie
	var enc1, enc2, enc3, enc4;
	// variables temporaires pour les decalages
	var chr1, chr2, chr3;
	
	// trim invalid characters in the beginning and in the end of the string
	encStr = encStr.replace(/%3D/g,"=");
	encStr = encStr.replace(/^[^a-zA-Z0-9\+\/\=]+|[^a-zA-Z0-9\+\/\=]+$/g,"");
	
	var len = encStr.length;
	var decOut = "";
	var i = 0;
	do
	{
		enc1 = this.iBase64[encStr.charCodeAt(i++)];
		enc2 = this.iBase64[encStr.charCodeAt(i++)];
		enc3 = this.iBase64[encStr.charCodeAt(i++)];
		enc4 = this.iBase64[encStr.charCodeAt(i++)];
		
		chr1 = (enc1 << 2) | (enc2 >> 4);
		chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
		chr3 = ((enc3 & 3) << 6) | enc4;
		
		decOut += String.fromCharCode(chr1);
		if (enc3 != -1)
		{
			decOut += String.fromCharCode(chr2);
		}
		if (enc4 != -1)
		{
			decOut += String.fromCharCode(chr3);
		}
	}
	while (i < len);
	if (i != len)
	{
	 return "";
	}
	return decOut;
}
