加解密代码
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, "