function Base64() { // private property b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; b64padchar="="; // public method for encoding this.encode = function (bytes) { var i; var c = 0x0; var ret = ""; for (i = 0; i + 3 <= bytes.length; i += 3) { c = ((bytes[i] & 0xFF) << 16) ^ ((bytes[i + 1]& 0xFF) << 8) ^ (bytes[i + 2] & 0xFF); ret += b64map.charAt(c >>> 18) + b64map.charAt((c & 0x3F000) >>> 12) + b64map.charAt((c & 0xFC0) >>> 6) + b64map.charAt(c & 0x3F); } if (i == (bytes.length-1)) { c = bytes[i] & 0xFF; ret += b64map.charAt((c & 0xFC) >>> 2) + b64map.charAt((c & 0x3) << 4); } else if (i + 1 == (bytes.length-1)) { c = ((bytes[i] & 0xFF) << 8) ^ (bytes[i + 1] & 0xFF); ret += b64map.charAt((c & 0xFC00) >>> 10) + b64map.charAt((c & 0x3F0) >>> 4) + b64map.charAt((c & 0xF) << 2); } while ((ret.length & 3) > 0) { ret += b64padchar; } return ret; } // public method for decoding this.decode = function (s) { var ret = []; var i; for (i = 0; i < s.length; i += 4) { var block = []; var v1 = b64map.indexOf(s.charAt(i)); if (v1 < 0) continue; block.push(v1); var v2 = b64map.indexOf(s.charAt(i+1)); if (v2 < 0) continue; block.push(v2); var third = s.charAt(i+2); if(third == b64padchar) { //Handle Block ret = ret.concat(convertb64Block(block)); break; } else { var v3 = b64map.indexOf(third); if (v3 < 0) continue; block.push(v3); } var fourth = s.charAt(i+3); if(fourth == b64padchar) {//Handle Block ret = ret.concat(convertb64Block(block)); break; } else { var v4 = b64map.indexOf(fourth); if (v4 < 0) continue; block.push(v4); } ret = ret.concat(convertb64Block(block));//Handle Block } return ret; } function convertb64Block(bytes) { var ret = []; var i = 0; if (bytes.length == 4) { ret.push(((bytes[i] & 0x3F) << 2) ^ ((bytes[i + 1] & 0x30) >>> 4)); ret.push(((bytes[i + 1] & 0xF) << 4) ^ ((bytes[i + 2] & 0x3C) >>> 2)); ret.push(((bytes[i + 2] & 0x3) << 6) ^ (bytes[i + 3] & 0xFF)); } else if (bytes.length == 3) { ret.push(((bytes[i] & 0x3F) << 2) ^ ((bytes[i + 1] & 0x30) >>> 4)); ret.push(((bytes[i + 1] & 0xF) << 4) ^ ((bytes[i + 2] & 0x3C)>>>2)); } else if (bytes.length == 2) { ret.push(((bytes[i] & 0x3F) << 2) ^ ((bytes[i+1] & 0x30)>>>4)); } return ret; } }