var base16 = "0123456789abcdef";
var base32 = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v');
var base64 = 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', '+', '/');

function base16_decode (input)
{
	if (typeof input == "number" || input.length < 13)
	{
		return parseInt (input, 16); // Da se ulozit jako jedno cislo (52 bitove, javascript pracuje s 52 bit)
	}
	var output = new Array();
	for (var i = 0; i < input.length; i++) // Kazde 2 znaky tvori vystup 1 byt
	{
		output[output.length] = String.fromCharCode(parseInt (input.charAt(i), 16) << 4 | parseInt (input.charAt(++i), 16));
	}
	return output.join('');
}

function base16_encode (input)
{
	var output = "";
	if (typeof input == "number")
	{
		return input.toString(16);
	}
	
	for (var i = 0; i < input.length; i++) // Projdu pres vsechny vstupni byty
	{
		output += base16.charAt((input.charCodeAt(i) & 0xF0) >> 4);
		output += base16.charAt(input.charCodeAt(i) & 0xF);
	}
	return output;
}

function base32_decode (input)
{
	if (typeof input == "number" || input.length < 11)
	{
		return parseInt (input, 32); // Da se ulozit jako jedno cislo (50 bitove, javascript pracuje s 52 bit)
	}
	var output = new Array();
	var stop = input.length % 8; //
	if (stop == 0)
	{
		stop = 8;
	}
	for (start = 0; start < input.length; stop += 8, start = stop - 8) // Kazdych 8 znaku tvori vystup 5 bytu
	{
		bits = parseInt (input.substring(start, stop), 32);
		switch (Math.ceil((stop - start) / 8 * 5))
		{
			case 5:
				output[output.length] = String.fromCharCode((bits / 0x100 & 0xFF000000) >>> 24);
			case 4:
				output[output.length] = String.fromCharCode((bits & 0xFF000000) >>> 24);
			case 3:
				output[output.length] = String.fromCharCode((bits & 0xFF0000) >> 16);
			case 2:
				output[output.length] = String.fromCharCode((bits & 0xFF00) >> 8);
			default:
				output[output.length] = String.fromCharCode(bits & 0xFF);
		}
	}
	return output.join('');
}

function base32_encode (input)
{
	var leftovers = 0, output = "";
	if (typeof input == "number")
	{
		return input.toString(32);
	}
	
	for (var i = 0; i < input.length; i++) // Projdu pres vsechny vstupni byty
	{
		switch ((input.length - i) % 5) // Zbytek po deleni poctu bytu zbyvajicich do konce retezce (na zacatku retezce muze byt vystup posunuty)
		{
			case 0:
				if (output.length > 0 || (input.charCodeAt(i) & 0xF8))
				{
					output += base32[(input.charCodeAt(i) & 0xF8) >> 3];				// 12345
				}
				leftovers = (input.charCodeAt(i) & 0x07) << 2;						// 678--
			break;
			case 4:
				if (output.length > 0 || (input.charCodeAt(i) & 0xC0))
				{
					output += base32[leftovers | ((input.charCodeAt(i) & 0xC0) >> 6)];	// |||12
				}
				if (output.length > 0 || (input.charCodeAt(i) & 0x3E))
				{
					output += base32[(input.charCodeAt(i) & 0x3E) >> 1];				// 34567
				}
				leftovers = (input.charCodeAt(i) & 0x01) << 4;						// 8----
			break;
			case 3:
				if (output.length > 0 || (input.charCodeAt(i) & 0xF0))
				{
					output += base32[leftovers | ((input.charCodeAt(i) & 0xF0) >> 4)];	// |1234
				}
				leftovers = (input.charCodeAt(i) & 0x0F) << 1;						// 5678-
			break;
			case 2:
				if (output.length > 0 || (input.charCodeAt(i) & 0x80))
				{
					output += base32[leftovers | ((input.charCodeAt(i) & 0x80) >> 7)];	// ||||1
				}
				if (output.length > 0 || (input.charCodeAt(i) & 0x7C))
				{
					output += base32[(input.charCodeAt(i) & 0x7C) >> 2];				// 23456
				}
				leftovers = (input.charCodeAt(i) & 0x03) << 3;						// 78---
			break;
			case 1:
				if (output.length > 0 || input.charCodeAt(i) & 0xE0)
				{
					output += base32[leftovers | ((input.charCodeAt(i) & 0xE0) >> 5)];	// ||123
				}
				output += base32[input.charCodeAt(i) & 0x1F];						// 45678
			break;
		}
	}
	return output;
}

function base64_decode (input)
{
	alert ('Jeste neni naprogramovano.');
}

function base64_encode (input)
{
	var leftovers, output = "";
	if (typeof input == "number")
	{
		if (input / 0x1000000 & 0xF000000) // Bitove operatory pracuji s 32 bitovymi cisly, i kdyz javascript uklada cisla jako double (52 bitu mantisa)
		{
			output += base64[(input / 0x1000000 & 0xF000000) >> 24];
		}
		if (input / 0x1000000 & 0xFFC0000)
		{
			output += base64[(input / 0x1000000 & 0xFC0000) >> 18];
		}
		if (input / 0x1000000 & 0xFFFF000)
		{
			output += base64[(input / 0x1000000 & 0x3F000) >> 12];
		}
		if (input / 0x1000000 & 0xFFFF000)
		{
			output += base64[(input / 0x1000000 & 0xFC0) >> 6];
		}
		if (input / 0x1000000 & 0xFFFF000 || input & 0xFF000000)
		{
			output += base64[(input & 0x3F000000) >> 24];
		}
		if (input / 0x1000000 & 0xFFFF000 || input & 0xFFFC0000)
		{
			output += base64[(input & 0xFC0000) >> 18];
		}
		if (input / 0x1000000 & 0xFFFF000 || input & 0xFFFFF000)
		{
			output += base64[(input & 0x3F000) >> 12];
		}
		if (input / 0x1000000 & 0xFFFF000 || input & 0xFFFFFFC0)
		{
			output += base64[(input & 0xFC0) >> 6];
		}
		output += base64[input & 0x3F];
		return output;
	}
	
	for (var i = 0; i < input.length; i++)
	{
		switch (i % 3)
		{
			case 0:
				output += base64[(input.charCodeAt(i) & 0xFC) >> 2];				// 123456
				leftovers = (input.charCodeAt(i) & 0x03) << 4;						// 78----
			break;
			case 1:
				output += base64[leftovers | ((input.charCodeAt(i) & 0xF0) >> 4)];	// ||1234
				leftovers = (input.charCodeAt(i) & 0x0F) << 2;						// 5678--
			break;
			case 2:
				output += base64[leftovers | ((input.charCodeAt(i) & 0xC0) >> 6)];	// ||||12
				output += base64[input.charCodeAt(i) & 0x3F];						// 345678
			break;
		}
	}
	return output;
}
