as3corelib Tutorial:How to Use MD5Stream Class in Flex

golf-128x128 This class performs MD5 hash of an input stream in chunks. It is based on com.adobe.crypto.MD5 and can process data in chunks. Both block creation and hash computation are done together for whatever input is available so that the memory overhead at a time is always fixed. Memory usage is governed by two parameters: one is the amount of data passed in to update() and the other is memoryBlockSize. The latter comes into play only when the memory window exceeds the pre allocated memory window of flash player. Usage: create an instance, call update(data) repeatedly for all chunks and finally complete() which will return the md5 hash..

Search-256x256 Demo | DownloadDownload Full Project

This demo loads images into flash player with the new load() and save() features of FileReference provided by flash player 10, compute and compare hash strings of each image in order to find the duplicated images.

Properties:

1. memoryBlockSize

  1. public var memoryBlockSize:int = 16384

Change this value from the default (16384) in the range of MBs to actually affect GC as GC allocates in pools of memory

Methods:

1. complete()

  1. public function complete(input:ByteArray = null):String

Pass in chunks of the input data with update(), call complete() with an optional chunk which will return the final hash. Equivalent to the way java.security.MessageDigest works.

Parameters:

  1. input:ByteArray (default = null)The optional bytearray chunk which is the final part of the input

Returns:

String — A string containing the hash value

2. resetFields()

  1. public function resetFields():void

Re-initialize this instance for use to perform hashing on another input stream. This is called automatically by complete().

3. update()

  1. public function update(input:ByteArray):void

Pass in chunks of the input data with update(), call complete() with an optional chunk which will return the final hash. Equivalent to the way java.security.MessageDigest works.

Parameters:

  1. input:ByteArrayThe bytearray chunk to perform the hash on

Screenshot:

MD5Stream-01

Click “browser” to select images to be loaded and compared.

MD5Stream-02

Click “load” to load selected images and click the file name to display the related image.

MD5Stream-03

Click “check” to compute hash strings for each image file and compare them to determine the duplicated ones.

The following is full source code of MD5StreamDemo.mxml:

  1. >
  2. <?xml version="1.0" encoding="utf-8"?>
  3. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
  4.     layout="absolute" xmlns:net="flash.net.*"
  5.     creationComplete="initApp();">
  6.     <mx:Script>
  7.         <![CDATA[
  8.             import mx.controls.Alert;
  9.             import mx.controls.Image;
  10.             import mx.core.UIComponent;
  11.             import mx.graphics.codec.JPEGEncoder;
  12.             import mx.events.ListEvent;
  13.             import mx.utils.ObjectProxy;
  14.             import com.adobe.crypto.MD5Stream;
  15.            
  16.             private var frl:FileReferenceList;
  17.            
  18.             [Bindable]
  19.             private var selectedFilesDataProvider:Array;
  20.            
  21.             [Bindable]
  22.             private var loadCount:int = 0;
  23.            
  24.             private function initApp():void
  25.             {
  26.                 frl = new FileReferenceList();
  27.                 selectedFilesDataProvider = new Array();
  28.                
  29.                 frl.addEventListener(Event.SELECT,filesSelectHandler);
  30.                
  31.                 image = new Image();
  32.                 imageContainer.addChild(image);
  33.             }       
  34.            
  35.             private function browser():void
  36.             {
  37.                 panel.status = "browse";
  38.                
  39.                 frl.browse([new FileFilter("Images (*.jpg, *.jpeg, *.gif, *.png)", "*.jpg;*.jpeg;*.gif;*.png")]);
  40.             }
  41.            
  42.             private function filesSelectHandler(event:Event):void
  43.             {
  44.                 panel.status = "selected";
  45.                            
  46.                 selectedFilesDataProvider = new Array();
  47.                
  48.                 loadCount = 0;
  49.                
  50.                 image.graphics.clear();
  51.                 image.width = 0;
  52.                 image.height = 0;
  53.                
  54.                 var frObj:ObjectProxy;
  55.                
  56.                 for each(var fr:FileReference in frl.fileList)
  57.                 {
  58.                     frObj = new ObjectProxy();
  59.                     frObj.name = fr.name;
  60.                     frObj.target = fr;
  61.                     frObj.duplicated = null;
  62.                    
  63.                     selectedFilesDataProvider.push(frObj);
  64.                    
  65.                     fr.addEventListener(Event.COMPLETE,fileLoadCompleteHandler);
  66.                 }
  67.             }
  68.            
  69.             private function load():void
  70.             {
  71.                 panel.status = "loading";
  72.                
  73.                 for each(var fr:FileReference in frl.fileList)
  74.                 {
  75.                     fr.load();
  76.                 }
  77.             }
  78.                         
  79.             private function fileLoadCompleteHandler(event:Event):void
  80.             {
  81.                 loadCount++;
  82.                 if(loadCount == selectedFilesDataProvider.length)
  83.                 {
  84.                     panel.status = "load complete";
  85.                 }               
  86.             }
  87.            
  88.             private var image:Image;
  89.            
  90.             private function showImage(event:ListEvent):void
  91.             {
  92.                 var data:Object = event.itemRenderer.data.target.data;
  93.                
  94.                 if(data != null)
  95.                 {
  96.                     var loader:Loader = new Loader();
  97.                     loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler);                   
  98.                     loader.loadBytes(ByteArray(data));       
  99.                 }
  100.                 else
  101.                 {
  102.                     Alert.show("you should load all the images first");
  103.                 }
  104.             }
  105.            
  106.             private function completeHandler(event:Event):void
  107.             {
  108.                
  109.                 var bitmap:Bitmap = Bitmap(event.currentTarget.loader.content);
  110.                 var bitmapData:BitmapData = bitmap.bitmapData;
  111.                
  112.                 image.width = bitmapData.width;
  113.                 image.height = bitmapData.height;
  114.                
  115.                  image.graphics.clear();
  116.                 image.graphics.beginBitmapFill(bitmapData);
  117.                 image.graphics.drawRect(0,0,bitmapData.width,bitmapData.height);
  118.                 image.graphics.endFill();             
  119.             }
  120.            
  121.             private function checkDuplicate():void
  122.             {
  123.                 panel.status = "checking";   
  124.                 callLater(doCheck);           
  125.             }
  126.            
  127.             private function doCheck():void
  128.             {
  129.                 var encrypted:String = "";
  130.                 var md5Stream:MD5Stream = new MD5Stream();
  131.                 var md5Keys:Object = new Object();
  132.                
  133.                 for(var i:int = 0 ; i < selectedFilesDataProvider.length; i++)
  134.                 {
  135.                     var frObj:ObjectProxy = ObjectProxy(selectedFilesDataProvider[i]);
  136.                    
  137.                     var byteArray:ByteArray = ByteArray(frObj.target.data);
  138.                
  139.                     var byteArray1:ByteArray = new ByteArray();
  140.                     var byteArray2:ByteArray = new ByteArray();
  141.                     var byteArray3:ByteArray = new ByteArray();
  142.                    
  143.                     var position:int = byteArray.length / 3;
  144.                     byteArray.readBytes(byteArray1,0,position);
  145.                     byteArray.readBytes(byteArray2,0,position);
  146.                     byteArray.readBytes(byteArray3,0);
  147.                    
  148.                     md5Stream.update(byteArray1);
  149.                     md5Stream.update(byteArray2);
  150.                     md5Stream.update(byteArray3);
  151.                    
  152.                     encrypted = md5Stream.complete();
  153.                    
  154.                     // The codes above from line "var byteArray:ByteArray = ByteArray(frObj.target.data);"
  155.                     // are equal to "encrypted = md5Stream.complete(byteArray);", it just a demo to show
  156.                     // we are able to compute data , like stream, in chunks.
  157.  
  158.                    
  159.                     if(md5Keys.hasOwnProperty(encrypted))
  160.                     {
  161.                         frObj.duplicated = true;
  162.                         frObj.name = frObj.name + "(" + md5Keys[encrypted].name + ")";
  163.                     }
  164.                     else
  165.                     {
  166.                         md5Keys[encrypted] = frObj;
  167.                         md5Keys[encrypted].duplicated = false;
  168.                     }
  169.                 }
  170.                
  171.                 panel.status = "checked";
  172.             }
  173.         ]]>
  174.     </mx:Script>
  175.     <mx:Panel id="panel" 
  176.         title="MD5Stream Demo" 
  177.         width="100%" height="100%" layout="absolute">
  178.         <mx:HDividedBox width="100%" height="100%">
  179.             <mx:List id="selectedFiles" 
  180.                 height="100%"
  181.                 width="100%"
  182.                 itemClick="showImage(event);"             
  183.                 dataProvider="{selectedFilesDataProvider}">
  184.                 <mx:itemRenderer>
  185.                     <mx:Component>
  186.                         <mx:HBox>
  187.                             <mx:Label text="{data.name}" color="{data.duplicated == null?0x000000:(!data.duplicated)?0x0099ff:0xff0000}"/>
  188.                             <mx:Label text="{data.duplicated == null?'unchecked':(!data.duplicated)?'ready':'duplicated'}"/>
  189.                         </mx:HBox>
  190.                     </mx:Component>
  191.                 </mx:itemRenderer>
  192.             </mx:List>
  193.             <mx:Canvas id="imageContainer" width="100%" height="100%">
  194.                
  195.             </mx:Canvas>
  196.         </mx:HDividedBox>       
  197.         <mx:ControlBar>
  198.             <mx:Button label="browser" click="browser();"/>
  199.             <mx:Button label="load" click="load();"/>
  200.             <mx:Button label="check" enabled="{loadCount == selectedFilesDataProvider.length &amp;&amp; selectedFilesDataProvider.length!= 0}" click="checkDuplicate();"/>
  201.         </mx:ControlBar>
  202.     </mx:Panel>
  203. </mx:Application>

Enjoy!

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • Reddit
  • Technorati
  • StumbleUpon
  • Twitter
RSS Enjoy this Post? Subscribe to Ntt.cc

RSS Feed   RSS Feed     Email Feed  Email Feed
You can leave a response, or trackback from your own site.

One Response to “as3corelib Tutorial:How to Use MD5Stream Class in Flex”

  1. kg says:

    This is great! Did you have to do anything special to get Flex Builder to target the v10 classes? Mine won’t recognize FileReference.load()

Leave a Reply