XXTEA加解密as3和python分别实现

来源:互联网 发布:muji爽肤水 知乎 编辑:程序博客网 时间:2024/06/05 22:37

加解密代码

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)






原创粉丝点击