今天更新博客时,顺便翻看了一下以前写的的东西,发现08年写的一篇用Javascript进行Base64编码传送数据的文章。说实在的,当初写这篇东西的时候,自己几乎是不懂Javascript的,只是看到公司的产品在应对各种Location, Language以及各种页面编码设置,存在大量的bug时,有心尝试一下用Base64解决的可能性,而最终并没有在产品中采用。
而如今(我指的是三年后的今天),我们的确在最新的产品中,成功使用了这一方案,并彻底摆脱了各种编码传送的问题。算法方面还是和以前一模一样,只不过,性能上做了局部优化,并在封装形式上有些变化,一如我提倡的Javascript用Java like的风格来写出Java程序员可以维护的代码一样,封装出一个js.util.Base64类:
- $package("js.util");
-
-
js.util.Base64 = new function (){
-
var base64chars = "ABCDEFGHIJKLMNOP" +
-
"QRSTUVWXYZabcdef"+
-
"ghijklmnopqrstuv"+
-
"wxyz0123456789@*"+
-
"-";
-
-
/**
-
* Encode a string to a Base64 string follow Bse64 regular.
-
* @param s, a normal string
-
* @return a Base64 string
-
*/
-
this.encode = function(s){
-
if(!s || s.length == 0) return s;
-
-
var d = [], b = ucs2_utf8(s), len = b.length,
-
b0, b1, b2, b3, i = 0, tmp;
-
-
while(i < len){
-
tmp = b[i++];
-
b0 = (tmp & 0xfc) >> 2;
-
b1 = (tmp & 0x03) << 4;
-
if(i < len){
-
tmp = b[i++];
-
b1 |= (tmp & 0xf0) >> 4;
-
b2 = (tmp & 0x0f) << 2;
-
if(i< len){
-
tmp = b[i++];
-
b2 |= (tmp & 0xc0) >> 6;
-
b3 = tmp & 0x3f;
-
}else{
-
b3 = 64; // 1 byte "-" is supplement
-
-
}
-
}else{
-
b2 = b3 = 64; // 2 bytes "-" are supplement
-
-
}
-
-
d.push(base64chars.charAt(b0));
-
d.push(base64chars.charAt(b1));
-
d.push(base64chars.charAt(b2));
-
d.push(base64chars.charAt(b3));
-
}
-
-
return d.join("");
-
};
-
-
/**
-
* Decode a Base64 string to a string follow Base64 regular.
-
* @param s, a Base64 string
-
* @return a normal string
-
*/
-
this.decode = function(s){
-
if(!s) return null;
-
-
var len = s.length;
-
if(len%4 != 0)
-
throw new Error(s+" is not a valid Base64 string.");
-
-
var b = [], i=0, j=0, e=0, c, tmp;
-
while(i < len){
-
c = base64chars.indexOf(s.charAt(i++));
-
tmp = c << 18;
-
c = base64chars.indexOf(s.charAt(i++));
-
tmp |= c << 12;
-
c = base64chars.indexOf(s.charAt(i++));
-
if(c < 64){
-
tmp |= c << 6;
-
c = base64chars.indexOf(s.charAt(i++));
-
if(c < 64){
-
tmp |= c;
-
}else{
-
e = 1;
-
}
-
}else{
-
e = 2;
-
i++;
-
}
-
-
b[j+2] = tmp & 0xff;
-
tmp >>= 8;
-
b[j+1] = tmp & 0xff;
-
tmp >>= 8;
-
b[j+0] = tmp & 0xff;
-
j += 3;
-
-
}
-
-
b.splice(b.length-e, e);
-
-
return utf8_ucs2(b);
-
-
};
-
-
/**
-
* Encodes a utf8 integer array to a ucs2 string.
-
* @param s, an integer array
-
* @return a string
-
*/
-
var utf8_ucs2 = function(s){
-
if(!s) return null;
-
var len = s.length;
-
if(len == 0) return "";
-
-
var d = [], c = 0, i = 0, tmp = 0;
-
while(i < len){
-
c = s[i++];
-
if((c & 0xe0) == 0xe0){
-
// 3 bytes
-
-
tmp = (c & 0x0f) << 12;
-
c = s[i++];
-
tmp |= ((c & 0x3f) << 6);
-
c = s[i++];
-
tmp |= (c & 0x3f);
-
}else
-
if((c & 0xc0) == 0xc0){
-
// 2 bytes
-
-
tmp = (c & 0x1f) << 6;
-
c = s[i++];
-
tmp |= (c & 0x3f);
-
}else{
-
// 1 byte
-
-
tmp = c;
-
}
-
-
d.push(String.fromCharCode(tmp));
-
}
-
-
return d.join("");
-
};
-
-
/**
-
* Encodes a ucs2 string to a utf8 integer array.
-
* @param s, a string
-
* @return an integer array
-
*/
-
var ucs2_utf8 = function(s){
-
if (!s) return null;
-
var d = [];
-
if (s == "") return d;
-
-
var c = 0, i = 0, j = 0, len = s.length;
-
while(i < len){
-
c = s.charCodeAt(i++);
-
if(c <= 0x7f){
-
// 1 byte
-
-
d[j++] = c;
-
}else
-
if((c >= 0x80) && (c <= 0x7ff)){
-
// 2 bytes
-
-
d[j++] = ((c >> 6) & 0x1f) | 0xc0;
-
d[j++] = (c & 0x3f) | 0x80;
-
}else{
-
// 3 bytes
-
-
d[j++] = (c >> 12) | 0xe0;
-
d[j++] = ((c >> 6) & 0x3f) | 0x80;
-
d[j++] = (c & 0x3f) | 0x80;
-
}
-
}
-
-
return d;
-
};
-
-
}();
阅读(2013) | 评论(2) | 转发(0) |