public static void useSequentialIds ( ) { if ( ! sequential ) { // get string that changes every 10 minutes TimeZone tz = TimeZone . getTimeZone ( "UTC" ) ; DateFormat df = new SimpleDateFormat ( "yyyyMMddHHmm" ) ; df . setTimeZone ( tz ) ; String date = df . format ( new Date ( ) ) . substring ( 0 , 11 ) ; // run an md5 hash of the string, no reason this needs to be secure byte [ ] digest ; try { MessageDigest md = MessageDigest . getInstance ( "MD5" ) ; digest = md . digest ( date . getBytes ( "UTF-8" ) ) ; } catch ( Exception e ) { throw new RuntimeException ( "Could not create hash of date for the sequential counter" , e ) ; } // create integer from first 4 bytes of md5 hash int x ; x = ( ( int ) digest [ 0 ] & 0xFF ) ; x |= ( ( int ) digest [ 1 ] & 0xFF ) << 8 ; x |= ( ( int ) digest [ 2 ] & 0xFF ) << 16 ; x |= ( ( int ) digest [ 3 ] & 0xFF ) << 24 ; COUNTER . set ( x ) ; } sequential = true ; }
Toggle UUID generator into sequential mode so the random segment is in order and increases by one . In sequential mode there is presumably a desire that UUIDs generated around the same time should begin with similar characters but this is difficult in a distributed environment . The solution is to set the counter value based on a hash of the UTC date and time up to a 10 minute precision . This means that UUID classes initialized at similar times should start with similar counter values but this is not guaranteed . If one of these classes is generating vastly more UUIDs than others then these counters can become skewed .