v1 method

String v1 ({Map<String, dynamic> options })

v1() Generates a time-based version 1 UUID

By default it will generate a string based off current time, and will return a string.

If an optional buffer list is provided, it will put the byte data into that buffer and return a buffer.

Optionally an offset can be provided with a start position in the buffer.

The first argument is an options map that takes various configuration options detailed in the readme.

http://tools.ietf.org/html/rfc4122.html#section-4.2.2

Implementation

String v1({Map<String, dynamic> options}) {
  var i = 0;
  var buf = new List<int>(16);
  options = (options != null) ? options : new Map();

  var clockSeq =
      (options['clockSeq'] != null) ? options['clockSeq'] : _clockSeq;

  // UUID timestamps are 100 nano-second units since the Gregorian epoch,
  // (1582-10-15 00:00). Time is handled internally as 'msecs' (integer
  // milliseconds) and 'nsecs' (100-nanoseconds offset from msecs) since unix
  // epoch, 1970-01-01 00:00.
  var mSecs = (options['mSecs'] != null)
      ? options['mSecs']
      : (new DateTime.now()).millisecondsSinceEpoch;

  // Per 4.2.1.2, use count of uuid's generated during the current clock
  // cycle to simulate higher resolution clock
  var nSecs = (options['nSecs'] != null) ? options['nSecs'] : _lastNSecs + 1;

  // Time since last uuid creation (in msecs)
  var dt = (mSecs - _lastMSecs) + (nSecs - _lastNSecs) / 10000;

  // Per 4.2.1.2, Bump clockseq on clock regression
  if (dt < 0 && options['clockSeq'] == null) {
    clockSeq = clockSeq + 1 & 0x3fff;
  }

  // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
  // time interval
  if ((dt < 0 || mSecs > _lastMSecs) && options['nSecs'] == null) {
    nSecs = 0;
  }

  // Per 4.2.1.2 Throw error if too many uuids are requested
  if (nSecs >= 10000) {
    throw new Exception('uuid.v1(): Can\'t create more than 10M uuids/sec');
  }

  _lastMSecs = mSecs;
  _lastNSecs = nSecs;
  _clockSeq = clockSeq;

  // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
  mSecs += 12219292800000;

  // time Low
  var tl = ((mSecs & 0xfffffff) * 10000 + nSecs) % 0x100000000;
  buf[i++] = tl >> 24 & 0xff;
  buf[i++] = tl >> 16 & 0xff;
  buf[i++] = tl >> 8 & 0xff;
  buf[i++] = tl & 0xff;

  // time mid
  var tmh = (mSecs ~/ 0x100000000 * 10000) & 0xfffffff;
  buf[i++] = tmh >> 8 & 0xff;
  buf[i++] = tmh & 0xff;

  // time high and version
  buf[i++] = tmh >> 24 & 0xf | 0x10; // include version
  buf[i++] = tmh >> 16 & 0xff;

  // clockSeq high and reserved (Per 4.2.2 - include variant)
  buf[i++] = clockSeq >> 8 | 0x80;

  // clockSeq low
  buf[i++] = clockSeq & 0xff;

  // node
  var node = (options['node'] != null) ? options['node'] : _nodeId;
  for (var n = 0; n < 6; n++) {
    buf[i + n] = node[n];
  }

  return unparse(buf);
}