blob: f6f5184c6fb34214644147e8a8cbee74ba671f06 [file] [log] [blame]
/**
* Random
*
* An ActionScript 3 implementation of a Random Number Generator
* Copyright (c) 2007 Henri Torgemane
*
* Derived from:
* The jsbn library, Copyright (c) 2003-2005 Tom Wu
*
* See LICENSE.txt for full license information.
*/
package com.hurlant.crypto.prng
{
import flash.utils.ByteArray;
import com.hurlant.util.Memory;
import flash.system.System;
import flash.system.Capabilities;
import flash.accessibility.AccessibilityProperties;
import flash.display.SWFVersion;
import flash.display.Stage;
import flash.utils.getTimer;
import flash.text.Font;
public class Random
{
private var state:IPRNG;
private var ready:Boolean = false;
private var pool:ByteArray;
private var psize:int;
private var pptr:int;
private var seeded:Boolean = false;
public function Random(prng:Class = null) {
if (prng==null) prng = ARC4;
state = new prng as IPRNG;
psize= state.getPoolSize();
pool = new ByteArray;
pptr = 0;
while (pptr <psize) {
var t:uint = 65536*Math.random();
pool[pptr++] = t >>> 8;
pool[pptr++] = t&255;
}
pptr=0;
seed();
}
public function seed(x:int = 0):void {
if (x==0) {
x = new Date().getTime();
}
pool[pptr++] ^= x & 255;
pool[pptr++] ^= (x>>8)&255;
pool[pptr++] ^= (x>>16)&255;
pool[pptr++] ^= (x>>24)&255;
pptr %= psize;
seeded = true;
}
/**
* Gather anything we have that isn't entirely predictable:
* - memory used
* - system capabilities
* - timing stuff
* - installed fonts
*/
public function autoSeed():void {
var b:ByteArray = new ByteArray;
b.writeUnsignedInt(System.totalMemory);
b.writeUTF(Capabilities.serverString);
b.writeUnsignedInt(getTimer());
b.writeUnsignedInt((new Date).getTime());
var a:Array = Font.enumerateFonts(true);
for each (var f:Font in a) {
b.writeUTF(f.fontName);
b.writeUTF(f.fontStyle);
b.writeUTF(f.fontType);
}
b.position=0;
while (b.bytesAvailable>=4) {
seed(b.readUnsignedInt());
}
}
public function nextBytes(buffer:ByteArray, length:int):void {
while (length--) {
buffer.writeByte(nextByte());
}
}
public function nextByte():int {
if (!ready) {
if (!seeded) {
autoSeed();
}
state.init(pool);
pool.length = 0;
pptr = 0;
ready = true;
}
return state.next();
}
public function dispose():void {
for (var i:uint=0;i<pool.length;i++) {
pool[i] = Math.random()*256;
}
pool.length=0;
pool = null;
state.dispose();
state = null;
psize = 0;
pptr = 0;
Memory.gc();
}
public function toString():String {
return "random-"+state.toString();
}
}
}