flash on 2011-12-19
package {
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.FileReference;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.utils.ByteArray;
import flash.utils.Endian;
import com.adobe.crypto.MD5;
import com.bit101.components.InputText;
import com.bit101.components.Label;
import com.bit101.components.PushButton;
import mx.utils.Base64Encoder;
import nochump.util.zip.CRC32;
public class FlashTest extends Sprite {
private var keyInput:InputText;
private var saveButton:PushButton;
private var crcLabel:Label;
private var body:ByteArray = null;
public function FlashTest() {
Wonderfl.capture_delay(0);
new Label(this, 10, 10, 'key');
new Label(this, 10, 40, 'input');
new Label(this, 10, 70, 'output');
keyInput = new InputText(this, 50, 10);
keyInput.width = 405;
keyInput.height = 20;
new PushButton(this, 50, 40, 'load', load);
saveButton = new PushButton(this, 50, 70, 'save', save);
saveButton.enabled = false;
crcLabel = new Label(this, 160, 70);
}
private function load(e:MouseEvent):void {
var fr:FileReference = new FileReference();
fr.addEventListener(Event.SELECT, function (e:Event):void {
fr.load();
});
fr.addEventListener(Event.COMPLETE, foo);
fr.browse();
}
private function save(e:MouseEvent):void {
if (!body) return;
new FileReference().save(body);
}
private function foo(e:Event):void {
var ba:ByteArray = e.target.data;
ba.endian = Endian.LITTLE_ENDIAN;
var checksum:int = ba.readInt();
body = new ByteArray();
ba.readBytes(body, 0, ba.bytesAvailable);
var key1:String = serializeString(keyInput.text);
var bd:BitmapData = new BitmapData(64, 64, true);
bd.perlinNoise(1.8984, 2.489894, 4, 48546, false, false, 15);
var key2:String = MD5.hash(serializeBytes(bd.getPixels(bd.rect)));
var key:ByteArray = new ByteArray();
key.writeUTFBytes(key1 + MD5.hash(key1) + key2);
RC4(key, body);
body.position = 0;
Wonderfl.log(body.readUnsignedInt());
var crc:CRC32 = new CRC32();
crc.update(body);
var checksum2:int = crc.getValue();
crcLabel.text = checksum + ' / ' + checksum2;
if (checksum == checksum2) crcLabel.text += ' CRC32 OK';
else crcLabel.text += ' CRC32 MISMATCH';
saveButton.enabled = true;
}
private function serializeString(s:String):String {
var chars:String = encodeURIComponent(s);
return 'y' + chars.length + ':' + chars;
}
private function serializeBytes(ba:ByteArray):String {
var encoder:Base64Encoder = new Base64Encoder();
encoder.encodeBytes(ba);
var chars:String = encoder.toString();
chars = chars.replace(/=/g, '');
chars = chars.replace(/\+/g, '%');
chars = chars.replace(/\//g, ':');
return 's' + chars.length + ':' + chars;
}
private function RC4(key:ByteArray, body:ByteArray):void {
// http://en.wikipedia.org/wiki/RC4
var i:int, j:int, k:int, swap:int;
var S:ByteArray = new ByteArray();
S.length = 256;
for (i = 0; i < 256; i++) S[i] = i;
for (i = j = 0; i < 256; i++) {
j =(j + S[i] + key[i % key.length]) & 255;
swap = S[i];
S[i] = S[j];
S[j] = swap;
}
i = j = 0;
for (i = j = k = 0; k < body.length; k++) {
i = (i + 1) & 255;
j = (j + S[i]) & 255;
swap = S[i];
S[i] = S[j];
S[j] = swap;
body[k] ^= S[(S[i] + S[j]) & 255];
}
}
}
}