Chinaunix首页 | 论坛 | 博客
  • 博客访问: 484261
  • 博文数量: 55
  • 博客积分: 1867
  • 博客等级: 上尉
  • 技术积分: 587
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-29 01:33
文章分类

全部博文(55)

文章存档

2013年(1)

2012年(2)

2011年(16)

2010年(11)

2009年(5)

2008年(10)

2007年(8)

2006年(2)

分类: 系统运维

2011-11-09 09:14:54

    今天更新博客时,顺便翻看了一下以前写的的东西,发现08年写的一篇用Javascript进行Base64编码传送数据的文章。说实在的,当初写这篇东西的时候,自己几乎是不懂Javascript的,只是看到公司的产品在应对各种Location, Language以及各种页面编码设置,存在大量的bug时,有心尝试一下用Base64解决的可能性,而最终并没有在产品中采用。
    
    而如今(我指的是三年后的今天),我们的确在最新的产品中,成功使用了这一方案,并彻底摆脱了各种编码传送的问题。算法方面还是和以前一模一样,只不过,性能上做了局部优化,并在封装形式上有些变化,一如我提倡的Javascript用Java like的风格来写出Java程序员可以维护的代码一样,封装出一个js.util.Base64类:

  1. $package("js.util");

  2. js.util.Base64 = new function (){
  3.     var base64chars = "ABCDEFGHIJKLMNOP" +
  4.         "QRSTUVWXYZabcdef"+
  5.         "ghijklmnopqrstuv"+
  6.         "wxyz0123456789@*"+
  7.         "-";

  8.     /**
  9.      * Encode a string to a Base64 string follow Bse64 regular.
  10.      * @param s, a normal string
  11.      * @return a Base64 string
  12.      */
  13.     this.encode = function(s){
  14.         if(!s || s.length == 0) return s;

  15.         var d = [], b = ucs2_utf8(s), len = b.length,
  16.         b0, b1, b2, b3, i = 0, tmp;

  17.         while(i < len){
  18.             tmp = b[i++];
  19.             b0 = (tmp & 0xfc) >> 2;
  20.             b1 = (tmp & 0x03) << 4;
  21.             if(i < len){
  22.                 tmp = b[i++];
  23.                 b1 |= (tmp & 0xf0) >> 4;
  24.                 b2 = (tmp & 0x0f) << 2;
  25.                 if(i< len){
  26.                     tmp = b[i++];
  27.                     b2 |= (tmp & 0xc0) >> 6;
  28.                     b3 = tmp & 0x3f;
  29.                 }else{
  30.                     b3 = 64; // 1 byte "-" is supplement

  31.                 }
  32.             }else{
  33.                 b2 = b3 = 64; // 2 bytes "-" are supplement

  34.             }

  35.             d.push(base64chars.charAt(b0));
  36.             d.push(base64chars.charAt(b1));
  37.             d.push(base64chars.charAt(b2));
  38.             d.push(base64chars.charAt(b3));
  39.         }

  40.         return d.join("");
  41.     };

  42.     /**
  43.      * Decode a Base64 string to a string follow Base64 regular.
  44.      * @param s, a Base64 string
  45.      * @return a normal string
  46.      */
  47.     this.decode = function(s){
  48.         if(!s) return null;

  49.         var len = s.length;
  50.         if(len%4 != 0)
  51.             throw new Error(s+" is not a valid Base64 string.");

  52.         var b = [], i=0, j=0, e=0, c, tmp;
  53.         while(i < len){
  54.             c = base64chars.indexOf(s.charAt(i++));
  55.             tmp = c << 18;
  56.             c = base64chars.indexOf(s.charAt(i++));
  57.             tmp |= c << 12;
  58.             c = base64chars.indexOf(s.charAt(i++));
  59.             if(c < 64){
  60.                 tmp |= c << 6;
  61.                 c = base64chars.indexOf(s.charAt(i++));
  62.                 if(c < 64){
  63.                     tmp |= c;
  64.                 }else{
  65.                     e = 1;
  66.                 }
  67.             }else{
  68.                 e = 2;
  69.                 i++;
  70.             }

  71.             b[j+2] = tmp & 0xff;
  72.             tmp >>= 8;
  73.             b[j+1] = tmp & 0xff;
  74.             tmp >>= 8;
  75.             b[j+0] = tmp & 0xff;
  76.             j += 3;
  77.             
  78.         }
  79.         
  80.         b.splice(b.length-e, e);

  81.         return utf8_ucs2(b);
  82.         
  83.     };

  84.     /**
  85.      * Encodes a utf8 integer array to a ucs2 string.
  86.      * @param s, an integer array
  87.      * @return a string
  88.      */
  89.     var utf8_ucs2 = function(s){
  90.         if(!s) return null;
  91.         var len = s.length;
  92.         if(len == 0) return "";

  93.         var d = [], c = 0, i = 0, tmp = 0;
  94.         while(i < len){
  95.             c = s[i++];
  96.             if((c & 0xe0) == 0xe0){
  97.                 // 3 bytes

  98.                 tmp = (c & 0x0f) << 12;
  99.                 c = s[i++];
  100.                 tmp |= ((c & 0x3f) << 6);
  101.                 c = s[i++];
  102.                 tmp |= (c & 0x3f);
  103.             }else
  104.                 if((c & 0xc0) == 0xc0){
  105.                     // 2 bytes

  106.                     tmp = (c & 0x1f) << 6;
  107.                     c = s[i++];
  108.                     tmp |= (c & 0x3f);
  109.                 }else{
  110.                     // 1 byte

  111.                     tmp = c;
  112.                 }
  113.             
  114.             d.push(String.fromCharCode(tmp));
  115.         }
  116.         
  117.         return d.join("");
  118.     };

  119.     /**
  120.      * Encodes a ucs2 string to a utf8 integer array.
  121.      * @param s, a string
  122.      * @return an integer array
  123.      */
  124.     var ucs2_utf8 = function(s){
  125.         if (!s) return null;
  126.         var d = [];
  127.         if (s == "") return d;

  128.         var c = 0, i = 0, j = 0, len = s.length;
  129.         while(i < len){
  130.             c = s.charCodeAt(i++);
  131.             if(c <= 0x7f){
  132.                 // 1 byte

  133.                 d[j++] = c;
  134.             }else
  135.                 if((c >= 0x80) && (c <= 0x7ff)){
  136.                     // 2 bytes

  137.                     d[j++] = ((c >> 6) & 0x1f) | 0xc0;
  138.                     d[j++] = (c & 0x3f) | 0x80;
  139.                 }else{
  140.                     // 3 bytes

  141.                     d[j++] = (c >> 12) | 0xe0;
  142.                     d[j++] = ((c >> 6) & 0x3f) | 0x80;
  143.                     d[j++] = (c & 0x3f) | 0x80;
  144.                 }
  145.         }
  146.         
  147.         return d;
  148.     };

  149. }();
阅读(1993) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

重返人生2011-11-12 23:32:23

时间是最锋利的武器啊!

☆彼岸★花开2011-11-11 00:52:42

传说中的java??