How to generate unique id in Dart
Asked Answered
N

9

149

I write websocket chat. How to generate unique id for user?

now i use this code:

id = new DateTime.now().millisecondsSinceEpoch;

is there any more neat solution?

Noman answered 21/3, 2013 at 13:15 Comment(0)
S
210

1. There is a UUID pub package:

http://pub.dartlang.org/packages/uuid

example usage:

import 'package:uuid/uuid.dart';

// Create uuid object
var uuid = Uuid();

// Generate a v1 (time-based) id
uuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'

// Generate a v4 (random) id
uuid.v4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'

// Generate a v5 (namespace-name-sha1-based) id
uuid.v5(uuid.NAMESPACE_URL, 'www.google.com'); // -> 'c74a196f-f19d-5ea9-bffd-a2742432fc9c'

2. This src has a dart GUID generator

https://github.com/MikeMitterer/AndroidIconGenerator.DART/blob/445884924/lib/src/model/communication/GUIDGen.dart

I'll not post the function src here directly as there is no apparent licence with it, but example usage is as follows:

final String uuid = GUIDGen.generate();
Shir answered 21/3, 2013 at 13:49 Comment(7)
Just a word of caution: this does not rely on strong random data. Therefore, the generated UUIDs should not be considered cryptographically strong. Whether it matters or not, I'll leave it to the reader to decide.Laniferous
thanks, i know, I will make an additional check the list of existing uuidsNoman
@KaiSellgren This is a pretty old post, but I think I could enrich it by asking a question here. You said that "this does not rely on strong random data". Can you elaborate that? I mean, how could we make it stronger?Heartland
@Heartland The library seems to now have an alternative function for random data generation: github.com/Daegalus/dart-uuid/blob/master/lib/uuid_util.dart -- I have not verified nor tested how strong that is, but you can do it rather trivially by calculating the chi square distribution. My Github page has a project for determining random data strength if you are curious.Laniferous
How can I use uuid multi times? I need to parse it in two different fields I have define final String image_name = Uuid().v1(); but every time I get differnt result.Manon
How can I crate from string? thing about that, when you using a database transfer object?Roseleeroselia
Should the uuid object stay the same throughout the application or can it be remade for example on every object constructor call?Minter
U
85

In year 2020 you can do UniqueKey(); which is a built in class:

https://api.flutter.dev/flutter/foundation/UniqueKey-class.html

Note

A key that is only equal to itself.

This cannot be created with a const constructor because that implies that all instantiated keys would be the same instance and therefore not be unique.

Unlace answered 16/2, 2020 at 12:30 Comment(12)
I think the intended use of this class is for Widgets and not to be used as ID's in a db.Inevitable
@Inevitable so this class is not secure as a unique ID? Why?Unpleasantness
@Unpleasantness If you take a look at the class you can clearly see that it creates a key that it's unique only inside the app. This meaning that if you save you key outside the app like in a DB you might recreate again the same unique key later. check Here from row 83 to 103 and there's also a discussion if you want to take a look at itInevitable
Thank you Gino, but 16^5 is enough randomness for me. This UnikeKey() works fine for my utility. Of course is not cryptographically safe, but it is a quick and built-in method.Unpleasantness
@Rufus It's not about crypto yet if it works for your utility then you should use it. Like they say "If it works then dont touch it!"Inevitable
I was looking for a way to provide an ID for my model objects. Using UniqueKey() from the flutter framework would mean my redux models would depend on a UI framework. Therefore I just use a simple library to generate a unique identifier.Aiden
@Inevitable , u can use UniqueKey().toString() to get a unique string literal that can be saved in database. The Flutter team has overriden the toString() method of the UniqueKey class to return the underlying id associated with the key, check here.Houppelande
@SonXuanNguyen Glad they had the chance to improve it! Thanks for the update!Inevitable
I recommend reading more about UniqueKey in this answer There are some important things to understand about this class.Sy
Run and see how many duplicates you'll get with such method: void main() { final keyList = List<String>.generate(2000, (_) => UniqueKey().toString()); var map = <String, int>{}; for (var key in keyList) { map[key] = map.containsKey(key) ? map[key]! + 1 : 1; } map.removeWhere((key, count) => count == 1); print('duplicates: ${map.length} \n$map'); }Middlings
It may be sufficient randomness but it is "built-in" to the Widgets package which is a UI dependency and you are talking about generating IDs for a database so you are mixing/coupling logic and UI framework which is an unclean architecture.Tabescent
Is the hashCode guaranteed to always be unique?Docent
S
28

I use microseconds instead of milliseconds, which is much more accurate and there is no need to add any package.

 String idGenerator() {
    final now = DateTime.now();
    return now.microsecondsSinceEpoch.toString();
  }
Sloven answered 24/4, 2022 at 8:29 Comment(4)
Yes - reasonable and no dependenciesMaximilian
I notice the difference that micro always adds 000 at the back.Affiance
A warning for anyone using this on Flutter web: "Note that this value does not fit into 53 bits (the size of a IEEE double). A JavaScript number is not able to hold this value.".Countermark
I have run into a situation in a Flutter Windows app where the generated microseconds repeat several times when used in a for loop (like when making a whole bunch of records in a row). Be careful since this may not be a guaranteed way to get unique values.Eclosion
D
14

Besides from uuid, you can also try this to generate small unique keys:

https://pub.dev/packages/nanoid

They even have a collision calculator:

https://zelark.github.io/nano-id-cc/

Dochandorrach answered 11/4, 2021 at 7:7 Comment(2)
This is a very good alternative soluition if you working with such a small device or id batch.Noguchi
Long live nanoid!Clavichord
T
4

This method will generate unique Id similar to (-N4pvg_50j1CEqSb3SZt)

String getCustomUniqueId() {
  const String pushChars =
      '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
  int lastPushTime = 0;
  List lastRandChars = [];
  int now = DateTime.now().millisecondsSinceEpoch;
  bool duplicateTime = (now == lastPushTime);
  lastPushTime = now;
  List timeStampChars = List<String>.filled(8, '0');
  for (int i = 7; i >= 0; i--) {
    timeStampChars[i] = pushChars[now % 64];
    now = (now / 64).floor();
  }
  if (now != 0) {
    print("Id should be unique");
  }
  String uniqueId = timeStampChars.join('');
  if (!duplicateTime) {
    for (int i = 0; i < 12; i++) {
      lastRandChars.add((Random().nextDouble() * 64).floor());
    }
  } else {
    int i = 0;
    for (int i = 11; i >= 0 && lastRandChars[i] == 63; i--) {
      lastRandChars[i] = 0;
    }
    lastRandChars[i]++;
  }
  for (int i = 0; i < 12; i++) {
    uniqueId += pushChars[lastRandChars[i]];
  }
  return uniqueId;
}
Tympanum answered 18/6, 2022 at 8:32 Comment(0)
E
4

I've built a scenario to generate a unique cryptographically secure random id. with 4 random generations id's

  1. First 4 Alphabets from an alphabets list [a-z].

  2. Middle 4 digits from a digits list [0-9].

  3. DateTime 4 microseconds since epoch substring 8 - 12 because they change frequently.

  4. Last 4 Alphabets from an alphabets list [a-z].

Screen Shots of Generated id's:

first generated id second generated id third generated id

A Function to Call

  randomIdGenerator() {
  var ranAssets = RanKeyAssets();
  String first4alphabets = '';
  String middle4Digits = '';
  String last4alphabets = '';
  for (int i = 0; i < 4; i++) {
    first4alphabets += ranAssets.smallAlphabets[
        math.Random.secure().nextInt(ranAssets.smallAlphabets.length)];

    middle4Digits +=
        ranAssets.digits[math.Random.secure().nextInt(ranAssets.digits.length)];

    last4alphabets += ranAssets.smallAlphabets[
        math.Random.secure().nextInt(ranAssets.smallAlphabets.length)];
  }

  return '$first4alphabets-$middle4Digits-${DateTime.now().microsecondsSinceEpoch.toString().substring(8, 12)}-$last4alphabets';
}

Class for list

    class RanKeyAssets {
  var smallAlphabets = [
    'a',
    'b',
    'c',
    'd',
    'e',
    'f',
    'g',
    'h',
    'i',
    'j',
    'k',
    'l',
    'm',
    'n',
    'o',
    'p',
    'q',
    'r',
    's',
    't',
    'u',
    'v',
    'w',
    'x',
    'y',
    'z'
  ];
  var digits = [
    '0',
    '1',
    '2',
    '3',
    '4',
    '5',
    '6',
    '7',
    '8',
    '9',
  ];
}
Epencephalon answered 1/8, 2022 at 11:3 Comment(0)
K
1

If you like MongoDB style ids you could consider this small package that will help create the object id:

https://pub.dev/packages/crossplat_objectid

import 'package:bson_objectid/bson_objectid.dart';

main() {
  ObjectId id1 = new ObjectId();
  print(id1.toHexString());

  ObjectId id2 = new ObjectId.fromHexString('54495ad94c934721ede76d90');
  print(id2.timestamp);
  print(id2.machineId);
  print(id2.processId);
  print(id2.counter);
}
Kathrynkathryne answered 15/5, 2020 at 12:59 Comment(0)
B
1

There is also https://pub.dev/packages/xid which is lock free and has a Unicity guaranteed for 16,777,216 (24 bits) unique ids per second and per host/process

import 'package:xid/xid.dart';

void main() {
  var xid = Xid();
  print('generated id: $xid');

}
Brawl answered 21/12, 2021 at 17:42 Comment(0)
S
0

To generate a unique ID you can use this code

import 'package:id_gen/id_gen.dart';

print(UuidV4Gen().get());

from the lightweight and well-tested Dart package https://pub.dev/packages/id_gen

Surah answered 21/1 at 18:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.