XXTEA加解密as3和python分别

发布时间:2019-09-22 07:41:01编辑:auto阅读(1797)

    加解密代码

    package 
    {
    	import flash.display.Shape;
    	import flash.display.Sprite;
    	import flash.utils.ByteArray;
    	
    	public class Test extends Sprite {
    		
    		public function Test() {
    			var dataStr:String = "Today's weather is good.";
    			var data:ByteArray = new ByteArray();
    			data.writeMultiByte(dataStr, "utf-8");
    			
    			var keyStr:String = "abcxyz123";
    			var key:ByteArray = new ByteArray();
    			key.writeMultiByte(keyStr, "utf-8");
    			trace("data:", dataStr);
    			trace("key:", keyStr);
    			
    			//加密
    			var encryptData:ByteArray = XXTEA.encrypt(data, key);
    			var content:String = Base64.encodeByteArray(encryptData);
    			trace("encode: " + content);
    			
    			//解密
    			encryptData = Base64.decodeToByteArray(content);
    			var sourceBtyes:ByteArray = XXTEA.decrypt(encryptData, key);
    			var sourceStr:String = sourceBtyes.toString();
    			trace("decode: " + sourceStr );
    			
    		}
    	}
    }

    XXTEA加解密用到了Base64,以下是XXTEA和Base64的代码


    XXTEA的代码 

    package 
    {	
    	import flash.utils.ByteArray;   
    	import flash.utils.Endian;   
    	
    	public class XXTEA {  
    		
    		private static const delta:uint = uint(0x9E3779B9);   
    		
    		private static function LongArrayToByteArray(data:Array, includeLength:Boolean):ByteArray {   
    			var length:uint = data.length;   
    			var n:uint = (length - 1) << 2;   
    			if (includeLength) {   
    				var m:uint = data[length - 1];   
    				if ((m < n - 3) || (m > n)) {   
    					return null;   
    				}   
    				n = m;   
    			}   
    			var result:ByteArray = new ByteArray();   
    			result.endian = Endian.LITTLE_ENDIAN;   
    			for (var i:uint = 0; i < length; i++) {   
    				result.writeUnsignedInt(data[i]);   
    			}   
    			if (includeLength) {   
    				result.length = n;   
    				return result;   
    			}   
    			else {   
    				return result;   
    			}   
    		}  
    		
    		private static function ByteArrayToLongArray(data:ByteArray, includeLength:Boolean):Array {   
    			var length:uint = data.length;   
    			var n:uint = length >> 2;   
    			if (length % 4 > 0) {   
    				n++;   
    				data.length += (4 - (length % 4));   
    			}   
    			data.endian = Endian.LITTLE_ENDIAN;   
    			data.position = 0;   
    			var result:Array = [];   
    			for (var i:uint = 0; i < n; i++) {   
    				result[i] = data.readUnsignedInt();   
    			}   
    			if (includeLength) {   
    				result[n] = length;   
    			}   
    			data.length = length;   
    			return result;   
    		} 
    		
    		public static function encrypt(data:ByteArray, key:ByteArray):ByteArray {   
    			if (data.length == 0) {   
    				return new ByteArray();   
    			}   
    			var v:Array = ByteArrayToLongArray(data, true);   
    			var k:Array = ByteArrayToLongArray(key, false);   
    			if (k.length < 4) {   
    				k.length = 4;   
    			}   
    			var n:uint = v.length - 1;   
    			var z:uint = v[n];   
    			var y:uint = v[0];   
    			var mx:uint;   
    			var e:uint;   
    			var p:uint;   
    			var q:uint = uint(6 + 52 / (n + 1));   
    			var sum:uint = 0;   
    			while (0 < q--) {   
    				sum = sum + delta;   
    				e = sum >>> 2 & 3;   
    				for (p = 0; p < n; p++) {   
    					y = v[p + 1];   
    					mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);   
    					z = v[p] = v[p] + mx;   
    				}   
    				y = v[0];   
    				mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);   
    				z = v[n] = v[n] + mx;   
    			}   
    			return LongArrayToByteArray(v, false);   
    		}   
    		
    		public static function decrypt(data:ByteArray, key:ByteArray):ByteArray {   
    			if (data.length == 0) {   
    				return new ByteArray();   
    			}   
    			var v:Array = ByteArrayToLongArray(data, false);   
    			var k:Array = ByteArrayToLongArray(key, false);   
    			if (k.length < 4) {   
    				k.length = 4;   
    			}   
    			var n:uint = v.length - 1;   
    			var z:uint = v[n - 1];   
    			var y:uint = v[0];   
    			var mx:uint;   
    			var e:uint;   
    			var p:uint;   
    			var q:uint = uint(6 + 52 / (n + 1));   
    			var sum:uint = q * delta;   
    			while (sum != 0) {   
    				e = sum >>> 2 & 3;   
    				for (p = n; p > 0; p--) {   
    					z = v[p - 1];   
    					mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);   
    					y = v[p] = v[p] - mx;   
    				}   
    				z = v[n];   
    				mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);   
    				y = v[0] = v[0] - mx;   
    				sum = sum - delta;   
    			}   
    			return LongArrayToByteArray(v, true);   
    		}   
    	}   
    }  

    Base64的代码

    package
    {	
    	import flash.utils.ByteArray;    
    	
    	public class Base64 {    
    
    		private static const BASE64_CHARS:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";             
    		
    		
    		public static const version:String = "1.0.0";    
    		
    		public static function encode(data:String):String {    
    			// Convert string to ByteArray    
    			var bytes:ByteArray = new ByteArray();    
    			bytes.writeUTFBytes(data);    
    			
    			// Return encoded ByteArray    
    			return encodeByteArray(bytes);    
    		}    
    		
    		public static function encodeByteArray(data:ByteArray):String {    
    			// Initialise output    
    			var output:String = "";    
    			
    			// Create data and output buffers    
    			var dataBuffer:Array;    
    			var outputBuffer:Array = new Array(4);    
    			
    			// Rewind ByteArray    
    			data.position = 0;    
    			
    			// while there are still bytes to be processed    
    			while (data.bytesAvailable > 0) {    
    				// Create new data buffer and populate next 3 bytes from data    
    				dataBuffer = new Array();    
    				for (var i:uint = 0; i < 3 && data.bytesAvailable > 0; i++) {    
    					dataBuffer[i] = data.readUnsignedByte();    
    				}    
    				
    				// Convert to data buffer Base64 character positions and     
    				// store in output buffer    
    				outputBuffer[0] = (dataBuffer[0] & 0xfc) >> 2;    
    				outputBuffer[1] = ((dataBuffer[0] & 0x03) << 4) | ((dataBuffer[1]) >> 4);    
    				outputBuffer[2] = ((dataBuffer[1] & 0x0f) << 2) | ((dataBuffer[2]) >> 6);    
    				outputBuffer[3] = dataBuffer[2] & 0x3f;    
    				
    				// If data buffer was short (i.e not 3 characters) then set    
    				// end character indexes in data buffer to index of '=' symbol.    
    				// This is necessary because Base64 data is always a multiple of    
    				// 4 bytes and is basses with '=' symbols.    
    				for (var j:uint = dataBuffer.length; j < 3; j++) {    
    					outputBuffer[j + 1] = 64;    
    				}    
    				
    				// Loop through output buffer and add Base64 characters to     
    				// encoded data string for each character.    
    				for (var k:uint = 0; k < outputBuffer.length; k++) {    
    					output += BASE64_CHARS.charAt(outputBuffer[k]);    
    				}    
    			}    
    			
    			// Return encoded data    
    			return output;    
    		}    
    		
    		public static function decode(data:String):String {    
    			// Decode data to ByteArray    
    			var bytes:ByteArray = decodeToByteArray(data);    
    			
    			// Convert to string and return    
    			return bytes.readUTFBytes(bytes.length);    
    		}    
    		
    		public static function decodeToByteArray(data:String):ByteArray {    
    			// Initialise output ByteArray for decoded data    
    			var output:ByteArray = new ByteArray();    
    			
    			// Create data and output buffers    
    			var dataBuffer:Array = new Array(4);    
    			var outputBuffer:Array = new Array(3);    
    			
    			// While there are data bytes left to be processed    
    			for (var i:uint = 0; i < data.length; i += 4) {    
    				// Populate data buffer with position of Base64 characters for    
    				// next 4 bytes from encoded data    
    				for (var j:uint = 0; j < 4 && i + j < data.length; j++) {    
    					dataBuffer[j] = BASE64_CHARS.indexOf(data.charAt(i + j));    
    				}    
    				
    				// Decode data buffer back into bytes    
    				outputBuffer[0] = (dataBuffer[0] << 2) + ((dataBuffer[1] & 0x30) >> 4);    
    				outputBuffer[1] = ((dataBuffer[1] & 0x0f) << 4) + ((dataBuffer[2] & 0x3c) >> 2);            
    				outputBuffer[2] = ((dataBuffer[2] & 0x03) << 6) + dataBuffer[3];    
    				
    				// Add all non-padded bytes in output buffer to decoded data    
    				for (var k:uint = 0; k < outputBuffer.length; k++) {    
    					if (dataBuffer[k+1] == 64) break;    
    					output.writeByte(outputBuffer[k]);    
    				}    
    			}    
    			
    			// Rewind decoded data ByteArray    
    			output.position = 0;    
    			
    			// Return decoded data    
    			return output;    
    		}    
    		
    		public function Base64() {    
    			throw new Error("Base64 class is static container only");    
    		}    
    	}    
    }  

    ===========以下是Python代码=====================

    xxtea.py

    import struct  
      
    _DELTA = 0x9E3779B9  
      
    def _long2str(v, w):  
        n = (len(v) - 1) << 2  
        if w:  
            m = v[-1]  
            if (m < n - 3) or (m > n): return ''  
            n = m  
        s = struct.pack('<%iL' % len(v), *v)  
        return s[0:n] if w else s  
      
    def _str2long(s, w):  
        n = len(s)  
        m = (4 - (n & 3) & 3) + n  
        s = s.ljust(m, "\0")  
        v = list(struct.unpack('<%iL' % (m >> 2), s))  
        if w: v.append(n)  
        return v  
      
    def encrypt(str, key):  
        if str == '': return str  
        v = _str2long(str, True)  
        k = _str2long(key.ljust(16, "\0"), False)  
        n = len(v) - 1  
        z = v[n]  
        y = v[0]  
        sum = 0  
        q = 6 + 52 // (n + 1)  
        while q > 0:  
            sum = (sum + _DELTA) & 0xffffffff  
            e = sum >> 2 & 3  
            for p in xrange(n):  
                y = v[p + 1]  
                v[p] = (v[p] + ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffff  
                z = v[p]  
            y = v[0]  
            v[n] = (v[n] + ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[n & 3 ^ e] ^ z))) & 0xffffffff  
            z = v[n]  
            q -= 1  
        return _long2str(v, False)  
      
    def decrypt(str, key):  
        if str == '': return str  
        v = _str2long(str, False)  
        k = _str2long(key.ljust(16, "\0"), False)  
        n = len(v) - 1  
        z = v[n]  
        y = v[0]  
        q = 6 + 52 // (n + 1)  
        sum = (q * _DELTA) & 0xffffffff  
        while (sum != 0):  
            e = sum >> 2 & 3  
            for p in xrange(n, 0, -1):  
                z = v[p - 1]  
                v[p] = (v[p] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))) & 0xffffffff  
                y = v[p]  
            z = v[n]  
            v[0] = (v[0] - ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[0 & 3 ^ e] ^ z))) & 0xffffffff  
            y = v[0]  
            sum = (sum - _DELTA) & 0xffffffff  
        return _long2str(v, True)

    测试test.py

    # -*- coding: utf-8 -*-
    if __name__ == "__main__":  
        import xxtea, base64
        data = "Today's weather is good."
        key = "abcxyz123"
        
        #加密
        s = xxtea.encrypt(data, key)
        s = base64.b64encode(s)
        print '加密后:' + repr(s)
    
        #解密
        s = base64.b64decode(s)
        s = xxtea.decrypt(s, key)
        print repr(s)






关键字