public class Steganography { static private var __instance:Steganography; static public function getInstance():Steganography{ if(__instance==null) __instance = new Steganography(); return __instance; }
private var __totalWidth:int; private var __totalHeight:int; private var __point:Point;
public function Steganography() { if(__instance!=null) throw new Error("plz use Steganography.getInstance()"); }
public function encode(oBD:BitmapData, txt:String):BitmapData{ var txtLen:int = txt.length; var txtLenLen:int = String(txtLen).length;
public class Demo2 extends MovieClip { public var btnBrowse:Button; public var btnEncode:Button; public var btnSave:Button; public var btnLoad:Button; public var btnDecode:Button;
public var spImg:ScrollPane; public var spImg2:ScrollPane;
public var txtInput:TextArea; public var txtOutput:TextArea;
private var __fileReference:FileReference = new FileReference(); private var __fileReference2:FileReference = new FileReference();
public function Demo2() { btnBrowse.addEventListener(MouseEvent.CLICK, onBtnBrowseClick); btnEncode.addEventListener(MouseEvent.CLICK, onBtnEncodeClick); btnSave.addEventListener(MouseEvent.CLICK, onBtnSaveClick); btnLoad.addEventListener(MouseEvent.CLICK, onBtnLoadClick); btnDecode.addEventListener(MouseEvent.CLICK, onBtnDecodeClick);
正當 Adobe 仍在努力於 Flash 10 on Mobile 與 Adobe AIR on Mobile 的開發時,Nokia 的 WRT(Nokia Web Runtime) 已經越來越擴大其領地了。
某種程度上,與 Adobe AIR 有著類似的概念:只要使用 html、javascript 這些既有且容易上手的開發技術,開發出網頁,再打包成某種 package,就可以安裝到有對應 Runtime 的手機環境上執行了。
現在,Nokia WRT 也提供了數種 plug-in 給知名的開發工具,包括: * Nokia WRT Plug-in 2.0 for Aptana Studio * Nokia WRT Extension for Adobe Dreamweaver * Nokia WRT Plug-in for Visual Studio
加上 Nokia 強調其手機平台的市占率,使得想要進入手機開發的內容提供商,可以認真的思考是否可以開始採用 Nokia WRT 來提供手機應用程式或服務了。
public class Main extends MovieClip{ private var __lcChackSingleApp:LocalConnection; public function Main(){ var lcName:String = getQualifiedClassName(this); __lcChackSingleApp = new LocalConnection(); try{ __lcChackSingleApp.connect(lcName); }catch(e:Error){ throw new Error("不允許同時執行兩個 flash"); return; }
init(); }
private function init():void{ throw new Error("init()"); } } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms;
using System.Security.Cryptography; using System.IO;
namespace TripleDES { public partial class Form1 : Form { public Form1() { InitializeComponent(); }
private void btnEncrypt_Click(object sender, EventArgs e) { try { // Create a new TripleDESCryptoServiceProvider object // to generate a key and initialization vector (IV). TripleDESCryptoServiceProvider tDESalg = new TripleDESCryptoServiceProvider();
// Create a string to encrypt. string sData = txtSource.Text;
public static byte[] EncryptTextToMemory(string Data, byte[] Key, byte[] IV) { try { TripleDESCryptoServiceProvider tDESalg = new TripleDESCryptoServiceProvider(); tDESalg.Padding = PaddingMode.PKCS7;
// Create a MemoryStream. MemoryStream mStream = new MemoryStream();
// Create a CryptoStream using the MemoryStream // and the passed key and initialization vector (IV). CryptoStream cStream = new CryptoStream(mStream, tDESalg.CreateEncryptor(Key, IV), CryptoStreamMode.Write);
// Convert the passed string to a byte array. //byte[] toEncrypt = new ASCIIEncoding().GetBytes(Data); byte[] toEncrypt = System.Text.Encoding.UTF8.GetBytes(Data);
// Write the byte array to the crypto stream and flush it. cStream.Write(toEncrypt, 0, toEncrypt.Length); cStream.FlushFinalBlock();
// Get an array of bytes from the // MemoryStream that holds the // encrypted data. byte[] ret = mStream.ToArray();
// Close the streams. cStream.Close(); mStream.Close();
public static string DecryptTextFromMemory(byte[] Data, byte[] Key, byte[] IV) { try { TripleDESCryptoServiceProvider tDESalg = new TripleDESCryptoServiceProvider(); tDESalg.Padding = PaddingMode.PKCS7;
// Create a new MemoryStream using the passed // array of encrypted data. MemoryStream msDecrypt = new MemoryStream(Data);
// Create a CryptoStream using the MemoryStream // and the passed key and initialization vector (IV). CryptoStream csDecrypt = new CryptoStream(msDecrypt, tDESalg.CreateDecryptor(Key, IV), CryptoStreamMode.Read);
// Create buffer to hold the decrypted data. byte[] fromEncrypt = new byte[Data.Length];
// Read the decrypted data out of the crypto stream // and place it into the temporary buffer. csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
//Convert the buffer into a string and return it. return System.Text.Encoding.UTF8.GetString(fromEncrypt); } catch (CryptographicException e) { Console.WriteLine("A Cryptographic error occurred: {0}", e.Message); return null; } }
}
}
至於我自己改寫的 Flex 範例,原則上只是因為在原範例中,IV 是編碼後所自動產生的,並可用於解碼,我將範例改成可以使用我們所填入文字欄位提供的 IV 值作編碼;以及上面我提過的有多顯示 IV(Base64) 的欄位。我就不再轉貼落落長的原始碼了。
public class SoundManager extends EventDispatcher { static public var SOUND_LOADED:String = "SOUND_LOADED";
private var __sounds:Object = new Object(); private var __soundClassLoaderList:Array = new Array();
static private var __instance:SoundManager; static public function getInstance():SoundManager{ if(__instance==null) __instance = new SoundManager(); return __instance; } public function SoundManager() { if(__instance!=null)throw new Error("please use SoundManager.getInstance()!!"); }
var soundClassLoader:ClassLoader = new ClassLoader(soundClassLibUrl); soundClassLoader.addEventListener(ClassLoader.CLASS_LOADED, onClassLoaded); soundClassLoader.addEventListener(ClassLoader.LOAD_ERROR, onClassLoadError); soundClassLoader.load();
/** * 載入 *.swf 完成 * @param e * */ private function onClassLoaded(e:Event):void{ dispatchEvent(new Event(SOUND_LOADED)); }
/** * 載入 *.swf 失敗 * @param e * */ private function onClassLoadError(e:Event):void{ trace(flash.utils.getQualifiedClassName(this), "onClassLoadError()", e.toString()); }
/** * 去各個 Class Loader 找一遍,找出指定的 Sound Class * @param id * @return * */ private function getSound(id:String):Sound{ var clsLoader:ClassLoader; var runtimeClassRef:Class;
public class ClassLoader extends EventDispatcher { public static var CLASS_LOADED:String = "classLoaded"; public static var LOAD_ERROR:String = "loadError"; private var loader:Loader; private var swfLib:String; private var request:URLRequest; private var loadedClass:Class;
static private var cache:Object = new Object(); private var lib:String;
public function ClassLoader(lib:String) { this.lib = lib;
loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler); loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,ioErrorHandler); loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityErrorHandler); }
public function load():void { if(cache[lib]!=null){ loadFromCache(); }else{ var urlLoader:URLLoader = new URLLoader(); urlLoader.dataFormat = URLLoaderDataFormat.BINARY; urlLoader.addEventListener(Event.COMPLETE, urlLoaderComplete); urlLoader.load(new URLRequest(lib)); } }
private function urlLoaderComplete(e:Event):void{ cache[lib] = (e.currentTarget as URLLoader).data; loadFromCache(); }
private function loadFromCache(){ var ba:ByteArray = cache[lib] as ByteArray;
var context:LoaderContext = new LoaderContext(); context.applicationDomain=ApplicationDomain.currentDomain;
loader.loadBytes(ba, context); }
public function getClass(className:String):Class { try { return loader.contentLoaderInfo.applicationDomain.getDefinition(className) as Class; } catch (e:Error) { throw new IllegalOperationError(className + " definition not found in " + swfLib); } return null; }
private function completeHandler(e:Event):void { dispatchEvent(new Event(ClassLoader.CLASS_LOADED)); }
private function ioErrorHandler(e:Event):void { dispatchEvent(new Event(ClassLoader.LOAD_ERROR)); }
private function securityErrorHandler(e:Event):void { dispatchEvent(new Event(ClassLoader.LOAD_ERROR)); }
var clsLoader:ClassLoader = new ClassLoader("asset.swf"); clsLoader.addEventListener(ClassLoader.CLASS_LOADED, onLoaded); clsLoader.load();
function onLoaded(e:Event):void{ var runtimeClassRef:Class = clsLoader.getClass("MC1"); var mc1:MovieClip = new runtimeClassRef() as MovieClip; addChild(mc1); }
To summarize, all the code here is Java code. None of the examples use reference to Flex SDK code nor Flash Player specific code, even the one that displays Flex controls. It all uses SWT code with its specific API.
Each example use a generic SWT wrapper written in Java and exported in ActionScript that control at runtime the access to standard Flash/Flex specific code. ......
當然也要注意一下其缺點:
...... The bad news
Now the bad news is when exploring the generated SWF files for each demo, we can see that what I call the SWT ActionScript wrapper is a SWF file named org.eclipse.swt.swf that weighs 960KB, common code for the examples 160KB and other files make any of the demo launched to load something like 2MB before to launch. It excludes to use any SWT generated application on any high audience public website. ......
/* Simple SWF parser Written by Denis V. Chumakov http://flashpanoramas.com/blog/ Use this code without any restrictions. */
// log string var parseLog:String;
// handlers for SWF tags // for example: // handlers[6] = parseJPEG; // to set your handler for DefineBitsJPEG tag. // you can find SWF file specifications in Google. var handlers:Array = [];
// parse SWF file function parseSWF(data:ByteArray) { parseLog = ""; data.endian = Endian.LITTLE_ENDIAN; var format:String = data.readUTFBytes(3); var compressed:Boolean = format=="CWS"; if (format=="FWS" || format=="CWS") { parseLog += "SWF version "+data.readByte(); parseLog += ", size: "+data.readUnsignedInt(); } else { parseLog += "Not a Flash file."; return; } data.readBytes(data); data.length -= 8; if (compressed) { data.uncompress(); } data.position = 0; var frame:Array = readBox(data); parseLog += "\n"; parseLog += "Width: "+Math.round((frame[1]-frame[0])/20); parseLog += ", height: "+Math.round((frame[3]-frame[2])/20); var fps_f:uint = data.readUnsignedByte(); var fps_i:uint = data.readUnsignedByte(); parseLog += "\n"; parseLog += "FPS: "+(fps_i+fps_f/256); var count:uint = data.readUnsignedShort(); parseLog += "\n"; parseLog += "Total frames: "+count; parseLog += "\n"; while (data.bytesAvailable) { readSWFTag(data); } trace(parseLog); }
// read SWF tag and call handler if present function readSWFTag(data:ByteArray) { var tag:uint = data.readUnsignedShort(); var id:int = tag>>6; var size:int = tag&0x3F; if (size == 0x3F) { size = data.readUnsignedInt(); } parseLog += "\n"; parseLog += "Tag "+id; if (handlers[id]!=null) { var dump:ByteArray = new ByteArray(); if (size!=0) { data.readBytes(dump,0,size); } handlers[id](tag, id, size, dump); } else { data.position += size; } parseLog += "\tsize: "+size; }
// read compressed box format function readBox(data:ByteArray):Array { var c:Array = []; var current:uint = data.readUnsignedByte(); var size:uint = current>>3; var off:int = 3; for (var i:int=0; i<4; i+=1) { c[i] = current<<(32-off)>>(32-size); off -= size; while (off<0) { current = data.readUnsignedByte(); c[i] |= off<-8?current<<(-off-8):current>>(-off-8); off += 8; } } return c; }
var loader:URLLoader = new URLLoader(); loader.dataFormat = URLLoaderDataFormat.BINARY; loader.addEventListener(Event.COMPLETE, loadComplete); // load complete handler function loadComplete(event:Event) { parseSWF(loader.data); } loader.load(new URLRequest("asset.swf"));
最後一句的 swf 檔名你自己換~
輸出結果:
SWF version 10, size: 1404 Width: 50, height: 50 FPS: 24 Total frames: 1
Tag 69 size: 4 Tag 77 size: 1284 Tag 9 size: 3 Tag 86 size: 12 Tag 83 size: 48 Tag 26 size: 6 Tag 1 size: 0 Tag 0 size: 0
其實 swf format 早已是公開的文件,有興趣的話可以自己寫一個 swf generator 或是 flash player。