All pastes #568533 Raw Edit

Danny's optimized UUID

public text v1 · immutable
·published 2007-06-15 16:06 UTC
rendered paste body
class UUID extends String
{
	static var rule30 = Rule30.createWithLength( 24 );
	
	var uuid : UUID;
	
	private static function hex( sbuf : StringBuf, n : Int )
	{
		var s = "";
		var hexChars = "0123456789ABCDEF";
		do {
			s = hexChars.charAt(n%16) + s;
			n = Std.int(n/16);
		} while( n > 0 );
		
		for( i in 0 ... 4-s.length ) // 4 Digits
			sbuf.addChar(48); // "0" 
		
		sbuf.add(s);
	}
	
	public function new ()
	{
		var str = new StringBuf();
		
		// TimeLow
		hex(str, rule30.getBits( 16 ));
		hex(str, rule30.getBits( 16 ));
		
		// TimeMid
		str.addChar(45); // "-"
		hex(str, rule30.getBits( 16 ));
		
		// VersionAndTimeHigh
		str.addChar(45);
		hex(str, (4 << 12) | rule30.getBits( 12 ));
		
		// VariantAndClockSeqHigh ClockSeqLow
		str.addChar(45);
		hex(str, (2 << 14) | rule30.getBits( 14 ));
		
		// Node
		str.addChar(45);
		hex(str, rule30.getBits( 16 ));
		hex(str, rule30.getBits( 16 ));
		hex(str, rule30.getBits( 16 ));
		
		super( str.toString() );
		
		uuid = this;
	}
	
	public function toString() : String {
		return uuid;
	}
}

private class Rule30
{
	static public function createWithLength ( length : Int ) : Rule30
	{
		var str = new StringBuf();
		
		for(i in 0 ... length) {
			str.addChar(  Math.floor(Math.random() * 256) );
		}
		
		return new Rule30( str.toString() );
	} 
	
	
	var cells : String;
	
	private function new ( cells : String )
	{
		this.cells = cells;
		
		var stir = cells.length * 16;
		for(i in 0 ... stir) {
			getBit();
		}
		
		var str = new StringBuf();
		for(i in 0 ... cells.length) {
			str.addChar( getBits( 8 ) );
		}
		
		this.cells = str.toString();
	}
	
	public function getBits ( length : Int ) : Int
	{
		if( length > 30 )	length = 30;
		
		var bits = 0;
		
		for(i in 0 ... length) {
			bits = (bits << 1) | getBit();
		}
		
		return bits;
	}
	
	function getBit () : Int
	{
		var cells = this.cells;
		var newCells = new StringBuf();
		var newCell : Int;
		var length = cells.length;
		var section : Int =	(cells.charCodeAt( length - 1 ) << 8) | cells.charCodeAt( 0 );
		
		for( pos in 0 ... length ) {
			section = (section << 8) | cells.charCodeAt( pos % length );
			newCell = 0;
			var i = 16;
			while( i-- > 8 ) {
				newCell = (newCell << 1) | ((30 >> ((section >> i) & 7)) & 1);
			}
			newCells.addChar( newCell );
		}
		
		this.cells = newCells.toString();
		
		return newCell & 1;
	}
}