import 'dart:math'; import 'dart:typed_data'; final _random = Random(); const _range = 1 << 32 - 1; // Issue with web int _lastTimestamp = 0; final List _byteToHex = List.generate(256, (i) { return i.toRadixString(16).padLeft(2, '0'); }); /// Generates a V7 UUID. /// /// Issue on JS web for the 2 most significant bytes. /// More details [here](https://dart.dev/resources/language/number-representation#bitwise-operations) String generateUuid() { var buf = Uint8List(16); final (ms, seq) = _getV7Time(); // Workaround for JS web: // final msHigh = (ms / pow(2, 32)).toInt(); // buf[0] = msHigh >> 8; // buf[1] = msHigh; buf[0] = ms >> 40; buf[1] = ms >> 32; buf[2] = ms >> 24; buf[3] = ms >> 16; buf[4] = ms >> 8; buf[5] = ms; buf[6] = 0x70 | ((seq >> 8) & 0x0f); buf[7] = seq; _populateRandomBytes4(buf, 8, 8); buf[8] = 0x80 | (buf[8] & 0x3f); return _format(buf); } (int, int) _getV7Time() { final time = DateTime.now(); int ms = time.millisecondsSinceEpoch; int us = time.microsecond; int now = (ms << 10) + us; if (ms < _lastTimestamp) { now = _lastTimestamp + 1; ms = now >> 10; us = now & 0x3ff; } _lastTimestamp = now; return (ms, us); } _populateRandomBytes4(Uint8List buf, int offset, int count) { for (var i = offset; i < offset + count; i += 4) { var k = _random.nextInt(_range); buf[i] = k; buf[i + 1] = k >> 8; buf[i + 2] = k >> 16; buf[i + 3] = k >> 24; } return buf; } String _format(Uint8List buf) { return '${_byteToHex[buf[0]]}${_byteToHex[buf[1]]}' '${_byteToHex[buf[2]]}${_byteToHex[buf[3]]}-' '${_byteToHex[buf[4]]}${_byteToHex[buf[5]]}-' '${_byteToHex[buf[6]]}${_byteToHex[buf[7]]}-' '${_byteToHex[buf[8]]}${_byteToHex[buf[9]]}-' '${_byteToHex[buf[10]]}${_byteToHex[buf[11]]}' '${_byteToHex[buf[12]]}${_byteToHex[buf[13]]}' '${_byteToHex[buf[14]]}${_byteToHex[buf[15]]}'; }