使用混合脚本编程来实现的Base64解码

    前几天用脚本做了个Base64编码程序,今天把解码程序也实现了,不过同样是使用JScript和VBScript混合编程来搞定的。

    解码的过程和编码过程是基本相同的,代码如下:

ExpandedBlockStart.gif ContractedBlock.gif < script  language ="javascript" > dot.gif
InBlock.gif
var Base64Alphabet2 = 
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif     'A' : 
0, 'B' : 1, 'C' : 2, 'D' : 3, 'E' : 4, 'F' : 5, 'G' : 6, 'H' : 7, 'I' : 8, 'J' : 9, 'K' : 10, 'L' : 11,
InBlock.gif     'M' : 
12, 'N' : 13, 'O' : 14, 'P' : 15, 'Q' : 16, 'R' : 17, 'S' : 18, 'T' : 19, 'U' : 20, 'V' : 21,
InBlock.gif     'W' : 
22, 'X' : 23, 'Y' : 24, 'Z' : 25, 'a' : 26, 'b' : 27, 'c' : 28, 'd' : 29, 'e' : 30, 'f' : 31,
InBlock.gif     'g' : 
32, 'h' : 33, 'i' : 34, 'j' : 35, 'k' : 36, 'l' : 37, 'm' : 38, 'n' : 39, 'o' : 40, 'p' : 41,
InBlock.gif     'q' : 
42, 'r' : 43, 's' : 44, 't' : 45, 'u' : 46, 'v' : 47, 'w' : 48, 'x' : 49, 'y' : 50, 'z' : 51,
InBlock.gif     '
0' : 52, '1' : 53, '2' : 54, '3' : 55, '4' : 56, '5' : 57, '6' : 58, '7' : 59, '8' : 60, '9' : 61,
InBlock.gif     
InBlock.gif     getCharCode : 
function(char)
ExpandedSubBlockStart.gifContractedSubBlock.gif     
dot.gif{
InBlock.gif          
if ( char == '+' )
ExpandedSubBlockStart.gifContractedSubBlock.gif          
dot.gif{
InBlock.gif               
return 62;
ExpandedSubBlockEnd.gif          }

InBlock.gif          
else if ( char == '/' )
ExpandedSubBlockStart.gifContractedSubBlock.gif          
dot.gif{
InBlock.gif               
return 63;
ExpandedSubBlockEnd.gif          }

InBlock.gif          
else if ( char == '=' )
ExpandedSubBlockStart.gifContractedSubBlock.gif          
dot.gif{
InBlock.gif               
return 0;
ExpandedSubBlockEnd.gif          }

InBlock.gif          
else    
ExpandedSubBlockStart.gifContractedSubBlock.gif          
dot.gif{
InBlock.gif               
return this[char];
ExpandedSubBlockEnd.gif          }
           
ExpandedSubBlockEnd.gif     }

ExpandedBlockEnd.gif}
;
None.gif
</ script >
ExpandedBlockStart.gif ContractedBlock.gif < script  language ="javascript" > dot.gif
InBlock.gif
function DecodeBase64(strCoding)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif    strCoding 
= strCoding.replace(/\s+/g, '');
InBlock.gif    
var padCount = 0
InBlock.gif    
if ( strCoding.charAt(strCoding.length-2== '=' )
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif         padCount 
= 2;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
else if ( strCoding.charAt(strCoding.length-1== '=' )
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif         padCount 
= 1;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
var count = strCoding.length/4;
InBlock.gif    
var hexString = '';
InBlock.gif    
var B64A2 = Base64Alphabet2; 
InBlock.gif    
for ( var i=0 ; i < count ; ++i )
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif         
var part1 = B64A2.getCharCode(strCoding.charAt(i*4));
InBlock.gif         
var part2 = B64A2.getCharCode(strCoding.charAt(i*4+1));
InBlock.gif         
var part3 = B64A2.getCharCode(strCoding.charAt(i*4+2));
InBlock.gif         
var part4 = B64A2.getCharCode(strCoding.charAt(i*4+3));
InBlock.gif         
var intA = (part1 << 2| (part2 >> 4);
InBlock.gif         
var intB = ((part2 & 0x0f ) << 4| (part3 >> 2);
InBlock.gif         
var intC = ((part3 & 0x03 ) << 6| part4;
InBlock.gif         
if ( intA < 0x10 )
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif             hexString 
+= '0';
ExpandedSubBlockEnd.gif         }
   
InBlock.gif         hexString 
+= intA.toString(16);
InBlock.gif         
if ( intB < 0x10 )
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif             hexString 
+= '0';
ExpandedSubBlockEnd.gif         }

InBlock.gif         hexString 
+= intB.toString(16);
InBlock.gif         
if ( intC < 0x10 )
ExpandedSubBlockStart.gifContractedSubBlock.gif         
dot.gif{
InBlock.gif              hexString 
+= '0';
ExpandedSubBlockEnd.gif         }
  
InBlock.gif         hexString 
+= intC.toString(16); 
ExpandedSubBlockEnd.gif    }

InBlock.gif    
if ( padCount > 0 )
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif         hexString 
= hexString.substr(0, hexString.length-padCount*2);
ExpandedSubBlockEnd.gif    }
    
InBlock.gif    
return hexString.getString();   
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
function jsParseInt(numString, radix)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif    
return parseInt(numString, radix);
ExpandedSubBlockEnd.gif}

InBlock.gif 
InBlock.gifString.prototype.getString 
= function()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif    
return vbGetString(this);
ExpandedBlockEnd.gif}

None.gif
</ script >
ExpandedBlockStart.gif ContractedBlock.gif < script  language ="vbscript" > dot.gif
InBlock.gif
function vbGetString(hexString)
InBlock.gif    
dim i, length, s
InBlock.gif    length 
= Len(hexString)/2
InBlock.gif    
for i=1 to length
InBlock.gif        charCode 
= jsParseInt(Mid(hexString, i*2-12), 16)
InBlock.gif        
if charCode < &H7F then
InBlock.gif            s 
= s & Chr(charCode)
InBlock.gif        
else
InBlock.gif            s 
= s & Chr(jsParseInt(Mid(hexString, i*2-14), 16))
InBlock.gif            i 
= i+1
InBlock.gif        
end if
InBlock.gif    
next
InBlock.gif    vbGetString 
= s
ExpandedBlockEnd.gif
end function
None.gif
</ script >

    其中第一段脚本定义的是一个类似hashtable的结构,这样的目的是为了避免每次去手动遍历在编码程序中定义的那个Base64Alphabet数组来做转换,并且这个结构的效率很高。原理解释可参看:比较JavaScript中的集合及其检索效率。对于这个hashtable,由于不能使用'+'、'/'和'='来做索引,所以实现了一个getCharCode的方法来作为代理,同时利用这个代理过程把=(pad)映射为了0。这样的好处就是我们不用在解码程序里专门去处理pad了,因为即使有pad,对于解码后的十六进制字符串也就是多些0在后面而已,并且是每有一个pad会对应多出一个'00'。在处理十六进制字符串之前执行一下:

None.gif      if  ( padCount  >   0  )
None.gif    {
None.gif         hexString 
=  hexString.substr( 0 , hexString.length - padCount * 2 );
None.gif    }

就行了。

    这个解码代码中还有两个地方可以优化,一是part1、part2、part3和part4那里,可以使用一个part数组 var part = new Array(4); 然后从strCoding里面去遍历4个连续有效的字符出来,然后再求intA,intB,intC。这样就可以省去解码开始前的数据清理工作 strCoding = strCoding.replace(/\s+/g, '');,同时还可以忽略非Base64Alphabet中定义的字符带来的错误干扰。二是intA、intB和intC也可以用一个数组来做,这样就可以把代码:

None.gif      if  ( intA  <   0x10  )
None.gif    {
None.gif         hexString 
+=  ' 0 ';
None.gif    }   
None.gif    hexString 
+=  intA.toString( 16 );
None.gif    
if  ( intB  <   0x10  )
None.gif    {
None.gif         hexString 
+=  ' 0 ';
None.gif    }
None.gif    hexString 
+=  intB.toString( 16 );
None.gif    
if  ( intC  <   0x10  )
None.gif    {
None.gif             hexString 
+=  ' 0 ';
None.gif    }  
None.gif    hexString 
+=  intC.toString( 16 ); 
None.gif

做成一个3次的循环,否则这样流水账般的代码太ugly了red_smile.gif

    当然这个解码程序的效率也不是很高,数据量太大的时候几乎就没有什么可用性了,这里我只是主观的觉得两个脚本引擎轮番调用可能也是性能瓶颈,如果您有好的优化方法,请不吝赐教哦thumbs_up.gif

    在线demo: http://zhilee.aehk.com/demo/TestBase64.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值