MD5 Checksum for Images (Binaries) in Actionscript 3
Luckily the hard part of the hash function for actionscript had already been written in the as3corelib which made my life significantly easier.
There is a bit of trickyness about the way Flash loads images by wrapping a swf around it which I'll save for another post - but once you have the byteArray data of the image generating the hash is pretty simple.
I just modified the corelib functions slightly and added a new function hashBinary. You can download the modified file from google code and hopefully it will get included by default in corelib.
public static function hashBinary( s:ByteArray ):String
// original function takes a string
public static function hash(s:String) :String
Beneath the surface they functions use all the same code. The changes made to the code are as follows:
- Rename hash function to be hashBinary.
- Change parameters of hashBinary to accept a ByteArray
- Change parameters of createBlocks to accept a ByteArray
- Change createBlocks to use array reference instead of s.getCharCodeAt()
- Create new hash() function which converts string to ByteArray and then call hashBinary passing in the ByteArray.
The changes should have no impact on the performance of the original hash function as it did the same conversion from a string to a binary but at a sligntly different location.
I've submitted a request to get this included in corelib so hopefully it will get added shortly.
Hope it helps Cheers, Mark




Glad you it was helpful to you - I've also been meaning to blog about it for a while - but I've written some code which pulls out the the jpeg data as URL Loader seems to wrap the JPG data into a swf file - probably for easier internal handling. If you need to compare the binary checksums that are generated by two different technologies - i.e. server and client side this becomes important. If you are only generating the MD5 checksums on the flash client side then you won't need to worry about it.
I'll get around to blogging about is soon but let me know if it's something you are working on and I'll publish it sooner.
Cheers,
Mark
I'm sure the followup post will come in handy for someone.
Thanks again!
Sorry for the N00b question, how do I get a AS file reference into a byte array so I can get the MD5 hash back.
Thanks
Dean
If you use URLLoader() and set the dataFormat to be binary, eg:
var urlReq:URLRequest =new URLRequest('http://www.example.com/image.jpg');
uLdr = new URLLoader();
uLdr.dataFormat = URLLoaderDataFormat.BINARY;
uLdr.addEventListener(Event.COMPLETE,imageLoadHandler);
uLdr.load(urlReq);
private function imageLoadHandler(e:Event):void{
trace('Image Loaded');
var rawFile:ByteArray = e.currentTarget.data;
}
Cheers,
Mark
There does not seem away to get the path of the file from the fileReference.
With the following I get
Unhandled ioError:. text=Error #2032: Stream Error. URL: file://ICS RGB.icc
I tried the object but event.target no go
I need to get the MD5 Hash of the file, I have a routine that will compare that hash with the files on the server and if this file does not exist upload, if it does exist don't upload.
The user selects the color profile from the browse(), I need to check that MD5 before uploading.
Thanks once again
private function onSelectFile(event:Event):void {
var urlReq:URLRequest =new URLRequest('file://' + event.target.name);
var uLdr:URLLoader = new URLLoader();
uLdr.dataFormat = URLLoaderDataFormat.BINARY;
uLdr.addEventListener(Event.COMPLETE,imageLoadHandler);
uLdr.load(urlReq);
}
private function imageLoadHandler(e:Event):void{
trace('Image Loaded');
var rawFile:ByteArray = e.currentTarget.data;
trace(MD5.hashBinary(rawFile))
}
I understand what you are trying to do now - is this for an app which is running in a browser as opposed to an AIR application?
If it's in a browser based app I suspect that it is not possible due to the way flash player handles the upload and download process (in order to work with the security sandboxes). The reason that I don't think it will work is that I think the Filereference class deliberately does not load the file directly into the flash play application space but passes it directly to the server.
I'd be very happy to be proved wrong as what you are trying to do would save lots of time if the files to be uploaded are large.
I haven't played with the file handling functionality in AIR yet but you may have a better chance of getting it done in AIR.
If you do figure it out please let me know.
Cheers,
Mark
I had a question about performance though. I have a project that generates an MD5 hash for jpg, xml, and flv files in an AIR application. The problem is that these files can get pretty large and files larger then 5mb destroy my computer when I pass them to the method.
Here is what happens to the Air process when I use the class on a 28mb flv file.
Before the file is loaded: 20mb 0%
after the file is loaded: 60mb 8% then 0%
after the file is passed to the hash method: 220mb 100% CPU
after the hash completes: 205mb 0% CPU
Maybe I'm doing something wrong or there is a way to throttle it?
Any suggestions would be greatly appreciated.