//XXTEA 对称加密算法
/* xxtea encryption arithmetic library. 
* Copyright (C) 2010 Ecranesoft Lab<web@ecranesoft.com>
* Version:      1.0
* LastModified: Apr 23, 2010
* This library is free.  You can redistribute it and/or modify it. 
*/
 
namespace string.xxtea 

//频繁使用的外部函数存为本地函数，减少名字空间查询次数。
var math = ..math;
var join = ..string.join;
var pack = ..string.pack; //存储为本地变量、加快速度
var left =  ..string.left

var function long2str(v, w) {
    var vl = #v;
    var sl = v[vl] & 0xffffffff;
 
    for (  i =1; vl )  
        v[i] = pack(v[i],v[i] >>> 8,v[i] >>> 16, v[i] >>> 24 ); 
   
    return (w) ? left( join(v),sl ) : join(v); 
}
 
var function str2long(s, w) {
    var len = #s;
    var v = {};
    for ( i = 0;   len-1;   4) {   
        v[ (i >> 2) + 1 ] =( (s[i + 1] ) 
                  | ( (s[i + 2] ) << 8)
                  | ( (s[i + 3] ) << 16)
                  | ( (s[i + 4] ) << 24) ) ;
    }
    if (w) {
        v[#v + 1] = len;
    }
     
    return v;
}
 
function encrypt(str, key) {
    if( type(str)!= type.string)
    	error("参数必须是字符串",2);
    	
    if (! #str )
        return "";
   
    var v = str2long(str, true);
    var k = str2long(key, false); 
    
    while(#k<4)
       ..table.push(k,0); 
       
    var n = #v - 1;
  
    var z = v[n+1];
    var y = v[1];
    var delta = 0x9E3779B9;
    var mx,e =0,0;
    var q = math.floor(6 + 52 / (n + 1)) ; 
    var sum = 0;
    
    while (q > 0 ) {
        q--; 
        sum = (sum + delta) & 0xffffffff;
        e = ( sum >>> 2 )  & 3;
        
        for (p = 0; n-1 ) {
            y = v[p + 2];
            mx = ( ( z >>> 5 ) ^ ( y << 2 ) ) + ( ( y >>> 3 )  ^ ( z << 4 ) ) ^ (sum ^ y) + (k[ ( (p & 3) ^ e) + 1] ^ z);
            v[p+1] = (v[p+1] + mx) & 0xffffffff;
            z = v[p+1];  
        }
        
         
        y = v[1];  
        mx = ( ( z >>> 5) ^ (y << 2) ) + ( (y >>> 3) ^ (z << 4) ) ^ (sum ^ y) + (k[ ( (n & 3) ^ e) + 1] ^ z);
        v[n+1] = (v[n+1] + mx) & 0xffffffff;
        z = v[n+1]
       
    }
 
    return long2str(v, false);
}
 
function decrypt(str, key) {
     if( type(str)!= type.string)
    	error("参数必须是字符串",2);
    	
    if (! #str )
        return "";
        
    var v = str2long(str, false);
    var k = str2long(key, false); 
    
    while(#k<4)
       ..table.push(k,0); 
       
    var n = #v - 1;
 
    var z = v[n ];
    var y = v[1];
    var delta = 0x9E3779B9;
    var mx,e =0,0;
    var q = math.floor(6 + 52 / (n + 1));
    var sum = (q * delta) & 0xffffffff;
     
    
    while ( sum ) {
        e = (sum >>> 2) & 3;
        
        for (p = n;1;-1) {
            z = v[p ];
            mx = ( (z >>> 5) ^ (y << 2) ) + ( (y >>> 3) ^ ( z << 4 ) ) ^ (sum ^ y) + (k[ ( (p & 3) ^ e) + 1] ^ z);
            v[p+1] = (v[p+1] - mx) & 0xffffffff;
            y = v[p+1] 
        }
         
        z = v[n+1];
        mx = ( (z >>> 5) ^ (y << 2) ) + ( (y >>> 3) ^ (z << 4) ) ^ (sum ^ y) + (k[ ( (0 & 3) ^ e ) +1] ^ z);
        v[1] = (v[1] - mx) & 0xffffffff;
        y = v[1]
        sum = (sum - delta) & 0xffffffff;
    }
  
    
   return long2str(v, true );
}  

/*intellisense(string.xxtea)
encrypt(__,"密钥") = xxtea加密
decrypt(__,"密钥") = xxtea解密
end intellisense*/

 