Skip to content

Instantly share code, notes, and snippets.

@jiggliemon
Created February 22, 2012 19:26
Show Gist options
  • Save jiggliemon/1886772 to your computer and use it in GitHub Desktop.
Save jiggliemon/1886772 to your computer and use it in GitHub Desktop.
/*
* Legitimize
* Requires the native JSON object || a comparable fill
*
*
*
**/
(function () {
var SML = {
generateSanitizedHash: function (object) {
return encodeURIComponent(this.Base64.encode(JSON.stringify(object)));
},
objectToHash: function (object) {
return this.generateSanitizedHash({"page_params": object});
},
hashToObject: function (hash) {
var obj = JSON.parse(this.Base64.decode(decodeURIComponent(hash)));
return obj.page_params || obj;
},
Base64: {
encode: function (text) {
if (/([^\u0000-\u00ff])/.test(text)){
throw new Error("Can't base64 encode non-ASCII characters.");
}
var digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
i = 0,
cur, prev, byteNum,
result=[];
while(i < text.length){
cur = text.charCodeAt(i);
byteNum = i % 3;
switch(byteNum){
case 0: //first byte
result.push(digits.charAt(cur >> 2));
break;
case 1: //second byte
result.push(digits.charAt((prev & 3) << 4 | (cur >> 4)));
break;
case 2: //third byte
result.push(digits.charAt((prev & 0x0f) << 2 | (cur >> 6)));
result.push(digits.charAt(cur & 0x3f));
break;
}
prev = cur;
i++;
}
if (byteNum == 0){
result.push(digits.charAt((prev & 3) << 4));
result.push("==");
} else if (byteNum == 1){
result.push(digits.charAt((prev & 0x0f) << 2));
result.push("=");
}
return result.join("");
}
,decode: function (text) {
//ignore white space
text = text.replace(/\s/g,"");
//first check for any unexpected input
if(!(/^[a-z0-9\+\/\s]+\={0,2}$/i.test(text)) || text.length % 4 > 0){
throw new Error("Not a base64-encoded string.");
}
//local variables
var digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
cur, prev, digitNum,
i=0,
result = [];
//remove any equals signs
text = text.replace(/=/g, "");
//loop over each character
while(i < text.length){
cur = digits.indexOf(text.charAt(i));
digitNum = i % 4;
switch(digitNum){
//case 0: first digit - do nothing, not enough info to work with
case 1: //second digit
result.push(String.fromCharCode(prev << 2 | cur >> 4));
break;
case 2: //third digit
result.push(String.fromCharCode((prev & 0x0f) << 4 | cur >> 2));
break;
case 3: //fourth digit
result.push(String.fromCharCode((prev & 3) << 6 | cur));
break;
}
prev = cur;
i++;
}
//return a string
return result.join("");
}
}
}
jQuery.prototype.legitimize = function (obj) {
var href= this.attr('href'),
hash,delimiter;
if(href.indexOf('app_data') === -1) {
hash = SML.objectToHash(obj || this.data());
delimiter = (href.indexOf('?') === -1)?'?':'&';
this.attr('href', href.concat(delimiter,'app_data=',hash) );
}
return this;
};
}());
var PageParams = {
generateSanitizedHash: function (object) {
return encodeURIComponent(this.Base64.encode(JSON.stringify(object)));
},
objectToHash: function (object) {
return this.generateSanitizedHash({"page_params": object});
},
hashToObject: function (hash) {
var obj = JSON.parse(this.Base64.decode(decodeURIComponent(hash)));
return obj.page_params || obj;
},
Base64: {
encode: function (text) {
if (/([^\u0000-\u00ff])/.test(text)){
throw new Error("Can't base64 encode non-ASCII characters.");
}
var digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
i = 0,
cur, prev, byteNum,
result=[];
while(i < text.length){
cur = text.charCodeAt(i);
byteNum = i % 3;
switch(byteNum){
case 0: //first byte
result.push(digits.charAt(cur >> 2));
break;
case 1: //second byte
result.push(digits.charAt((prev & 3) << 4 | (cur >> 4)));
break;
case 2: //third byte
result.push(digits.charAt((prev & 0x0f) << 2 | (cur >> 6)));
result.push(digits.charAt(cur & 0x3f));
break;
}
prev = cur;
i++;
}
if (byteNum == 0){
result.push(digits.charAt((prev & 3) << 4));
result.push("==");
} else if (byteNum == 1){
result.push(digits.charAt((prev & 0x0f) << 2));
result.push("=");
}
return result.join("");
}
,decode: function (text) {
//ignore white space
text = text.replace(/\s/g,"");
//first check for any unexpected input
if(!(/^[a-z0-9\+\/\s]+\={0,2}$/i.test(text)) || text.length % 4 > 0){
throw new Error("Not a base64-encoded string.");
}
//local variables
var digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
cur, prev, digitNum,
i=0,
result = [];
//remove any equals signs
text = text.replace(/=/g, "");
//loop over each character
while(i < text.length){
cur = digits.indexOf(text.charAt(i));
digitNum = i % 4;
switch(digitNum){
//case 0: first digit - do nothing, not enough info to work with
case 1: //second digit
result.push(String.fromCharCode(prev << 2 | cur >> 4));
break;
case 2: //third digit
result.push(String.fromCharCode((prev & 0x0f) << 4 | cur >> 2));
break;
case 3: //fourth digit
result.push(String.fromCharCode((prev & 3) << 6 | cur));
break;
}
prev = cur;
i++;
}
//return a string
return result.join("");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment