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; } }