Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ID - a unique ID/name generator for JavaScript
// Generate unique IDs for use as pseudo-private/protected names.
// Similar in concept to
// <http://wiki.ecmascript.org/doku.php?id=strawman:names>.
//
// The goals of this function are twofold:
//
// * Provide a way to generate a string guaranteed to be unique when compared
// to other strings generated by this function.
// * Make the string complex enough that it is highly unlikely to be
// accidentally duplicated by hand (this is key if you're using `ID`
// as a private/protected name on an object).
//
// Use:
//
// var privateName = ID();
// var o = { 'public': 'foo' };
// o[privateName] = 'bar';
var ID = function () {
// Math.random should be unique because of its seeding algorithm.
// Convert it to base 36 (numbers + letters), and grab the first 9 characters
// after the decimal.
return '_' + Math.random().toString(36).substr(2, 9);
};
@JustMikey

This comment has been minimized.

Copy link

@JustMikey JustMikey commented Feb 20, 2014

Thank you, it was helpful :)

@themesociety

This comment has been minimized.

Copy link

@themesociety themesociety commented Feb 21, 2014

Thanks, working great. :)

@carlosocarvalho

This comment has been minimized.

Copy link

@carlosocarvalho carlosocarvalho commented Feb 26, 2014

Thank you.

@niklas-r

This comment has been minimized.

Copy link

@niklas-r niklas-r commented Mar 7, 2014

This doesn't always match /_\w{9}/ and I'm not sure why. If someone could help me understand why that is I'd be grateful.

@ezakto

This comment has been minimized.

Copy link

@ezakto ezakto commented May 12, 2014

@nikias-r
Sometimes .toString() returns a string representation with length shorter than 9. ie:

var number = Math.random() // 0.9394456857981651
number.toString(36); // '0.xtis06h6'
var id = number.toString(36).substr(2, 9); // 'xtis06h6'
id.length >= 9; // false

This doesn't happen in all browsers (this example can be replicated in firefox, but not in chrome).

@javestruz

This comment has been minimized.

Copy link

@javestruz javestruz commented May 30, 2014

Thanks!

@ksaitor

This comment has been minimized.

Copy link

@ksaitor ksaitor commented Jul 8, 2014

Thank you! 👍

@yairsz

This comment has been minimized.

Copy link

@yairsz yairsz commented Feb 25, 2015

Excelent! Thank you!

@vcostin

This comment has been minimized.

Copy link

@vcostin vcostin commented Jun 19, 2015

Thanks!

@ravinsinghd

This comment has been minimized.

Copy link

@ravinsinghd ravinsinghd commented Jun 23, 2015

Thanks

@jhclaura

This comment has been minimized.

Copy link

@jhclaura jhclaura commented Jul 19, 2015

Works great! Thank!

@mkpenrod05

This comment has been minimized.

Copy link

@mkpenrod05 mkpenrod05 commented Nov 7, 2015

Simple and sweet, thanks!

@alexmorleyfinch

This comment has been minimized.

Copy link

@alexmorleyfinch alexmorleyfinch commented Nov 11, 2015

This is okay for generating less than 10 thousand unique IDs, but any more than 10 thousand and you are going to run into collisions.

I wrote a simple function to check for duplicates:

function checkDuplicates(generator, count){
  var hash = {};
  var dupe = [];
  for(var idx = 0; idx < count; ++idx){
    var gen = generator(idx); // generate our unique ID

    // if it already exists, then it has been duplicated
    if(typeof hash[gen] != 'undefined'){
      dupe.push({
        duplicate: gen,
        indexCreated: hash[gen],
        indexDuplicated: idx,
        duplicateCount: dupe.filter(function(cur){return cur.duplicate == gen}).length,
      });
    }
    hash[gen] = idx;
  }
  return dupe;
}

This function returns an array of duplicates. The format of a returned duplicate is as follows:

duplicate = {
  duplicate: "7srx2zt3zj2lnmi", // the generated id that was duplicated
  duplicateCount: 0,            // 0 is the first duplication, so 1 is the second duplication etc
  indexCreated: 133959,         // the index where the original ID was created
  indexDuplicated: 168948,      // the index where the original ID is duplicated
}

All you need to do is pass a function that returns your generated unique IDs, and the number of times you want to generate. The function is used like so:

function myUniqueID(){
  return Math.random().toString(36).slice(2);
}

checkDuplicates(myUniqueID, Math.pow(10, 4)); // Math.pow(10, 4) == 10'000 times

Calling the above returns an empty array. This means that no duplicates were found for less than 10 thousand iterations.

It you keep calling this, you keep getting 0 duplications. However, if you change the number of iterations to 100 thousand (or Math.pow(10, 5)), then you get between 0 and 3 duplicates. Change to 1 million and you get more than 100 duplicates. Change it to 10 million and you'll get thousands of duplicates.

Also, if you change it to 10 million you start to get multiple copies of duplicates! The same generated ID is not only duplicated once, but sometimes many times! If you run the following code, it will show you which keys were duplicated more than once (it may take a minute):

var duplicates = checkDuplicates(myUniqueID, Math.pow(10, 7)) // 10 MILLION

// now only show the duplicates that have a `duplicateCount` of more than 1
// (meaning they have been duplicated for a second time)
duplicates.filter(function(cur){
  return cur.duplicateCount > 0
});

When I run it with 10 million iterations, we get over 10 thousand duplicates, 10 of which have been duplicated twice

So as we can see, this function is okay for less than 10 thousand IDs, but any more and you are likely to run into collisions.

Therefore, do not use this to generate unique IDs. There are much better ways to do it.

However, a simple fix to get a lot less collisions would be to append the current time (new Date).getTime() to the returned ID. However, this still gets a few collisions when checking duplications for 10 million (still better than thousands)

Just out of interest, I found this function. It also uses Math.random, however it uses it multiple times, effectively reducing the chance that Math.random will generate the same numbers in the same order. It outputs a string in the format of a UUID (Universally Unique IDentifier).

function uniqueID(){
  function chr4(){
    return Math.random().toString(16).slice(-4);
  }
  return chr4() + chr4() +
    '-' + chr4() +
    '-' + chr4() +
    '-' + chr4() +
    '-' + chr4() + chr4() + chr4();
}

uniqueID() // "e27881c4-f924-b8f7-59d9-525878c7a812"

// NOTE: This format of 8 chars, followed by 3 groups of 4 chars, followed by 12 chars
//       is known as a UUID and is defined in RFC4122 and is a standard for generating unique IDs.
//       This function DOES NOT implement this standard. It simply outputs a string
//       that looks similar. The standard is found here: https://www.ietf.org/rfc/rfc4122.txt

If you call checkDuplicates with this, you will see that even with 10 million generations (or Math.pow(10, 7)) a collision is not detected, so this appears pretty safe.

I tried to run Math.pow(10, 8) which is 100 million, but it took forever and never finished. You may want to run your own tests for more than 100 million

@marcosschlup

This comment has been minimized.

Copy link

@marcosschlup marcosschlup commented Mar 3, 2016

For unique you can use Date.now() plus a random:

(Date.now().toString(36) + Math.random().toString(36).substr(2, 5)).toUpperCase()

@abdulhannanali

This comment has been minimized.

Copy link

@abdulhannanali abdulhannanali commented Mar 4, 2016

@marcosschlup How are you sure it'll be a random unique id?

@huang-xiao-jian

This comment has been minimized.

Copy link

@huang-xiao-jian huang-xiao-jian commented Apr 1, 2016

thanks, very helpful

@mniak

This comment has been minimized.

Copy link

@mniak mniak commented Jun 22, 2016

Really good

@natsimhan

This comment has been minimized.

Copy link

@natsimhan natsimhan commented Jul 1, 2016

Excellent solution alexmorleyfinch ;) And thx author for original id ;)

@iddan

This comment has been minimized.

Copy link

@iddan iddan commented Jul 21, 2016

Using it all the time! thank you

@hegwin

This comment has been minimized.

Copy link

@hegwin hegwin commented Sep 20, 2016

So cool. Thanks.

@mzhda

This comment has been minimized.

Copy link

@mzhda mzhda commented Oct 15, 2016

this is helpful

@MichaelDimitras

This comment has been minimized.

Copy link

@MichaelDimitras MichaelDimitras commented Oct 18, 2016

Thanks a lot alexmorleyfinch. This was really informative.

@rebers

This comment has been minimized.

Copy link

@rebers rebers commented Jun 16, 2017

I'm writing this in the hopes that others may find this on Google.

I had an issue that I'm using a v-for in Vue.js on a component, but in Vue 2.2+ you required :key to be set with a unique identifier. In my case the Array that it iterates over doesn't have any, so I had to generate one on demand (imagine a Bootstrap alerts manager component, e.g.). This will do just fine.

#vuejs #v-for

@hackeronline7

This comment has been minimized.

Copy link

@hackeronline7 hackeronline7 commented Jun 25, 2017

Thanks!

@balaarunreddyv1

This comment has been minimized.

Copy link

@balaarunreddyv1 balaarunreddyv1 commented Jun 28, 2017

Thanks

@iatsiuk

This comment has been minimized.

Copy link

@iatsiuk iatsiuk commented Jul 25, 2017

@devboxr :key must be unique inside the v-for loop, not for the entire vue component. in your case array has an index and that is enough

@up209d

This comment has been minimized.

Copy link

@up209d up209d commented Jul 26, 2017

I think the first one still the best, if you don't want it run into a collision just make one more

'-' + Math.random().toString(36).substr(2, 9) + '-' + Math.random().toString(36).substr(2, 9)

@beenotung

This comment has been minimized.

Copy link

@beenotung beenotung commented Aug 21, 2017

@devboxr iatsiuk's suggestion is more simple, for fun or other cases, you can get a unique id (without randomness) in a pretty effective way just by counting (Thanks to Javascript's single thread limitation).

You may take a reference on this demo:

export interface Counter {
  next(): number;
}

export function new_counter(init = 0): Counter {
  return {
    next: () => ++init
  };
}

export const Counter = new_counter(1);
@LindanTian

This comment has been minimized.

Copy link

@LindanTian LindanTian commented Oct 16, 2017

cool

@huzemin

This comment has been minimized.

Copy link

@huzemin huzemin commented Oct 26, 2017

Thinks

@axd7832

This comment has been minimized.

Copy link

@axd7832 axd7832 commented Nov 6, 2017

Simplicity is key. Thanks.

@n7best

This comment has been minimized.

Copy link

@n7best n7best commented Nov 13, 2017

good stuff

@radius314

This comment has been minimized.

Copy link

@radius314 radius314 commented Nov 15, 2017

👍

@Jeslopov

This comment has been minimized.

Copy link

@Jeslopov Jeslopov commented Dec 14, 2017

Thanks

@FatemeNoruzi

This comment has been minimized.

Copy link

@FatemeNoruzi FatemeNoruzi commented Dec 26, 2017

👍

@loyoliteabid

This comment has been minimized.

Copy link

@loyoliteabid loyoliteabid commented Dec 29, 2017

Thanks

@geezywap

This comment has been minimized.

Copy link

@geezywap geezywap commented Jan 12, 2018

@ManGysT

This comment has been minimized.

Copy link

@ManGysT ManGysT commented Jan 23, 2018

Thnaks man!

@mhcreative

This comment has been minimized.

Copy link

@mhcreative mhcreative commented Jan 25, 2018

Thanks. Great, simple script.

@shradha03

This comment has been minimized.

Copy link

@shradha03 shradha03 commented Feb 8, 2018

Thanks, it was of great help.

@lcherone

This comment has been minimized.

Copy link

@lcherone lcherone commented Feb 18, 2018

For any length IDs:

var ID = function (length) {
    if (!length) {
        length = 8
    }
    var str = ''
    for (var i = 1; i < length + 1; i = i + 8) {
        str += Math.random().toString(36).substr(2, 10)
    }
    return ('_' + str).substr(0, length)
}
@KalanaPerera

This comment has been minimized.

Copy link

@KalanaPerera KalanaPerera commented Feb 22, 2018

Thanks!!

@lcherone

This comment has been minimized.

Copy link

@lcherone lcherone commented Feb 26, 2018

Another way which uses a cryptographically secure random number generator, in UUID format.

var ID = () => {
  let array = new Uint32Array(8)
  window.crypto.getRandomValues(array)
  let str = ''
  for (let i = 0; i < array.length; i++) {
    str += (i < 2 || i > 5 ? '' : '-') + array[i].toString(16).slice(-4)
  }
  return str
}
@proishan11

This comment has been minimized.

Copy link

@proishan11 proishan11 commented Mar 13, 2018

Great! Can we write a unit test for this function? I am unable to figure out how to approach this. Thanks 😄

@ghost

This comment has been minimized.

Copy link

@ghost ghost commented Mar 30, 2018

Generating unique id's is a bigger headache than I thought. If there's anything to study its how to do this correctly because I've seen plenty of implementations that claim to work but are then quickly discredited.

@Planeur

This comment has been minimized.

Copy link

@Planeur Planeur commented Apr 14, 2018

Math.random() is not unique. But time stamp generated ids could be.

@Planeur

This comment has been minimized.

Copy link

@Planeur Planeur commented Apr 14, 2018

a simple way to do this:

(new Date().getTime()).toString(36)

@williamyeny

This comment has been minimized.

Copy link

@williamyeny williamyeny commented Apr 28, 2018

@Planeur Timestamp IDs are technically not unique because you could have the same ID if the IDs are generated within the same millisecond. Try combining timestamp and Math.random to make it even more unlikely for collisions

var ID = Date.now() + Math.random().toString().slice(2);

@krisan012

This comment has been minimized.

Copy link

@krisan012 krisan012 commented May 7, 2018

awesome thanks :D

@jorhel

This comment has been minimized.

Copy link

@jorhel jorhel commented Jun 13, 2018

Thankyou from the help.
My code:

function genID(){
    this.inner = [];
    this.unique = function( id ){
        for( var actID in this.inner ){
           if( actID === this.inner ){
                break;
               return false;
           }
        }
        return id;
    };
    this.gen = function( len ){
        len = typeof len !== "number" ? 36 : len;
        let id = false;
        while( !id ){
            id = this.unique('_' + (Date.now().toString( len ) + Math.random().toString( len ).substr(2, 5)).toUpperCase());
        }
         this.inner.push( id );
        console.log( this.inner );
        return id;
    };
    return this;
}

Use:

var foo = new genID();
console.log( foo.gen() );
console.log( foo.gen() );

@yukulele

This comment has been minimized.

Copy link

@yukulele yukulele commented Jul 18, 2018

Math.round((Math.random() * 36 ** 12)).toString(36);
// "u8dbda25zwik"
@Saifeddine-Rjab

This comment has been minimized.

Copy link

@Saifeddine-Rjab Saifeddine-Rjab commented Sep 1, 2018

Thanks this is very helpful

@robsongajunior

This comment has been minimized.

Copy link

@robsongajunior robsongajunior commented Sep 19, 2018

random and timestamp based at milions request maybe it is not unic...
.. should be implemented using RFC4122

Using JavaScript the correct way it is using UUID4, based in random.
uuid-v4.js

@Horse303

This comment has been minimized.

Copy link

@Horse303 Horse303 commented Sep 20, 2018

Hello. Thank you for posting this.
I did some testing to see how often collisions will occur (because for my nodejs RPG game, low length id is required and well, have as less collisions as possible).
I was very surprised with results.
(HashMap is my container, written in typescript)

I am failing to force this stupid post GUI to style the code. Therefore: code starts here:

`
results:
//stats results:
//1000 ids generated: 0 collisions
//10000 ids generated: 0 collisions
//100000 ids generated: 0 collisions
//1 milion ids generated: 0 collisions
//10 milion ids generated: 0 collisions

it('Collision finding', (done) => {
var hm = new HashMap<string, number>();
var iterations = 10000000;
var collisionsFound = 0;
for (let i = 0; i < iterations; i++) {
var id = Math.random().toString(36).substr(2, 9);
while (hm.contains(id)) {
console.log('id ${id} collision');
id = Math.random().toString(36).substr(2, 9);
collisionsFound++;
}
hm.insert(id, 2);
}
console.log('had ${collisionsFound} collisions in ${iterations} iterations');
});`

@Tusbahle

This comment has been minimized.

Copy link

@Tusbahle Tusbahle commented Oct 17, 2018

thanks !, it helped me....

@igorrybalko

This comment has been minimized.

Copy link

@igorrybalko igorrybalko commented Oct 23, 2018

Thanks, great solution.

@lmj0011

This comment has been minimized.

Copy link

@lmj0011 lmj0011 commented Nov 8, 2018

For anonymous analytic collecting from a pool of 10's of thousands of active users, maybe 100's, OP's solution should be fine to use.

However, I decided to tinker with my own implementation and came up with this (piggybacking off of @Planeur):

'_' + (new Date().getUTCMilliseconds().toString() + new Date().getTime().toString()).toString();

// "_4511541719590451"

not sure the base it would take to convert this into an alphanumerical string

@zhiwenjunjin

This comment has been minimized.

Copy link

@zhiwenjunjin zhiwenjunjin commented Nov 12, 2018

when you pick the substring, how can you be sure it is still unique?

@neyron163

This comment has been minimized.

Copy link

@neyron163 neyron163 commented Nov 21, 2018

Thanks

@jaitheking

This comment has been minimized.

Copy link

@jaitheking jaitheking commented Dec 10, 2018

Thank you. This is simple and easy to use

@notikatoti

This comment has been minimized.

Copy link

@notikatoti notikatoti commented Jan 19, 2019

Thank

@Waldemar999

This comment has been minimized.

Copy link

@Waldemar999 Waldemar999 commented Feb 21, 2019

thanks

@tripflex

This comment has been minimized.

Copy link

@tripflex tripflex commented Feb 26, 2019

var ID = () => {
let array = new Uint32Array(8)
window.crypto.getRandomValues(array)
let str = ''
for (let i = 0; i < array.length; i++) {
str += (i < 2 || i > 5 ? '' : '-') + array[i].toString(16).slice(-4)
}
return str
}

Works great thank you!

@yedincisenol

This comment has been minimized.

Copy link

@yedincisenol yedincisenol commented Mar 11, 2019

Thank you :)

@awesomeandrey

This comment has been minimized.

Copy link

@awesomeandrey awesomeandrey commented Apr 2, 2019

ty sir

@AlexisThink

This comment has been minimized.

Copy link

@AlexisThink AlexisThink commented Apr 4, 2019

Great! Thank you

@maurisrx

This comment has been minimized.

Copy link

@maurisrx maurisrx commented Apr 5, 2019

Thank you! Simple yet reliable.

@phaberest

This comment has been minimized.

Copy link

@phaberest phaberest commented Apr 22, 2019

Amazing, I was having issues using Device.uuid as it somehow breaks the new privacy rules, thanks!

@satish4linux

This comment has been minimized.

Copy link

@satish4linux satish4linux commented May 3, 2019

Thank you! worked great..!

@ronit-mukherjee

This comment has been minimized.

Copy link

@ronit-mukherjee ronit-mukherjee commented Jun 5, 2019

Thanks :), It's helpful

@c0d3r111

This comment has been minimized.

Copy link

@c0d3r111 c0d3r111 commented Jun 7, 2019

function random_id() {
  return '_' + (
    Number(String(Math.random()).slice(2)) + 
    Date.now() + 
    Math.round(performance.now())
  ).toString(36);
}
@DMPR-dev

This comment has been minimized.

Copy link

@DMPR-dev DMPR-dev commented Sep 12, 2019

thanks

@XemaA

This comment has been minimized.

Copy link

@XemaA XemaA commented Oct 5, 2019

@marcosschlup How are you sure it'll be a random unique id?

@abdulhannanali Date.now() will garentee that is unique :)

@klivak

This comment has been minimized.

Copy link

@klivak klivak commented Oct 29, 2019

@reheem, thank you.

@kievmontana

This comment has been minimized.

Copy link

@kievmontana kievmontana commented Nov 20, 2019

Thanks!

@mis101247

This comment has been minimized.

Copy link

@mis101247 mis101247 commented Dec 5, 2019

Thank you, clean and easily understand

@1453alabanda

This comment has been minimized.

Copy link

@1453alabanda 1453alabanda commented Dec 12, 2019

Thanks...

@Ablu

This comment has been minimized.

@boronotpalladium

This comment has been minimized.

Copy link

@boronotpalladium boronotpalladium commented Jan 9, 2020

Hi! Great code! I wrapped arround the local storage just to make sure it doesn't generate a identical string (even though the posibilities tends arround 0.027 hehe)
const entities_array = window.localStorage.getItem('entities_array') || [];
do{
var ID = '_' + Math.random().toString(36).substr(2);
} while(entities_array.find(entity => entity.ID === ID));
return ID;

@marcosschlup

This comment has been minimized.

Copy link

@marcosschlup marcosschlup commented Jan 9, 2020

You guys maybe want to use: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol

I don't see where this can help in the reported case. Any examples?

@Ablu

This comment has been minimized.

Copy link

@Ablu Ablu commented Jan 11, 2020

I don't see where this can help in the reported case. Any examples?

This depends on the exact use case of course. I landed on this gist after searching for "unique id javascript". I knew something like Symbol existed but did not know the name anymore and was looking for it again.

The page linked in the comment of this gist (http://wiki.ecmascript.org/doku.php?id=strawman:names) does not load for me at the moment, but this works for generating unique entries:

const privateName = Symbol();
const o = { 'public': 'foo' };
o[privateName] = 'bar';
const privateName2 = Symbol();
o[privateName2] = 'baz';
@JinkiJung

This comment has been minimized.

Copy link

@JinkiJung JinkiJung commented Jan 13, 2020

👍

@realVato

This comment has been minimized.

Copy link

@realVato realVato commented Jan 30, 2020

Saved my life, thank you!

@bilalyaqoob

This comment has been minimized.

Copy link

@bilalyaqoob bilalyaqoob commented Feb 22, 2020

Thank you

@vadymstebakov

This comment has been minimized.

Copy link

@vadymstebakov vadymstebakov commented Mar 15, 2020

Thank you :)

@WilliamsJose

This comment has been minimized.

Copy link

@WilliamsJose WilliamsJose commented Apr 2, 2020

Thank you, it's very helpful!

@c0d3r111

This comment has been minimized.

Copy link

@c0d3r111 c0d3r111 commented Apr 7, 2020

Here's another method:

const createID = () => {
    return Array(16)
      .fill(0)
      .map(() => String.fromCharCode(Math.floor(Math.random() * 26) + 97))
      .join('') + 
      Date.now().toString(24);
}
@aaaaaajie

This comment has been minimized.

Copy link

@aaaaaajie aaaaaajie commented Apr 23, 2020

thank you! :)

@Brydom

This comment has been minimized.

Copy link

@Brydom Brydom commented Apr 26, 2020

Just wanted to say that I've came here to use this snippet at least twice a month for the past couple years! Thanks :D

@Brydom

This comment has been minimized.

Copy link

@Brydom Brydom commented Apr 26, 2020

Great! Can we write a unit test for this function? I am unable to figure out how to approach this. Thanks 😄

@proishan11 A little late, but you could always just run a loop on it for a unit test.

var ID = function () {
  return '_' + Math.random().toString(36).substr(2, 9);
};

const unitTestWrittenWithoutAnyTestingFrameworkOops = () => {
  console.log('Testing ID() to ensure there are no duplicate IDs');
  
  const tests = 100000; // bigger the number the more accurate the results?
  const ids = [];
  
  for (let i = 0; i < tests; i++) {
    const newID = ID();
    
    if (ids.includes(newID)) return `Duplicate ID, test failed (${newID}).`;
    else ids.push(newID);
  }
  
  if (ids.length === tests) console.log('No duplicate IDs. Test passed.');
}

unitTestWrittenWithoutAnyTestingFrameworkOops();
@jailsonpaca

This comment has been minimized.

Copy link

@jailsonpaca jailsonpaca commented May 28, 2020

Thanks you! God bless you!

@robertpataki

This comment has been minimized.

Copy link

@robertpataki robertpataki commented Jun 12, 2020

Super helpful and works brilliantly, thank you for sharing 🌟

@karandeepvirk85

This comment has been minimized.

Copy link

@karandeepvirk85 karandeepvirk85 commented Jul 12, 2020

Cool..!

@leonardfischer

This comment has been minimized.

Copy link

@leonardfischer leonardfischer commented Aug 4, 2020

Nice snippet, thanks a lot!

@c0d3r111

This comment has been minimized.

Copy link

@c0d3r111 c0d3r111 commented Aug 4, 2020

Created another method with collision test.

const uid = () => {
  return String.fromCharCode(Math.floor(Math.random() * 26) + 97)
       + Math.random().toString(16).slice(2)
       + Date.now().toString(16).slice(4);
};

function collisionTest(iterations = 1e6) {
  let track = new Set();
  let count = -1;

  void console.time('Collision test');
  
  while (++count < iterations) {
    void track.add(uid());
  }
  
  void console.timeEnd('Collision test');
  void console.log('Total iterations:', iterations);
  void console.log('Total collisions:', iterations - track.size);
  void console.log('Total unique ids:', track.size);
}
@Anish6275

This comment has been minimized.

Copy link

@Anish6275 Anish6275 commented Aug 29, 2020

Thanks to all of you

@thaycacac

This comment has been minimized.

Copy link

@thaycacac thaycacac commented Aug 29, 2020

thanks

@chaitanyabd

This comment has been minimized.

Copy link

@chaitanyabd chaitanyabd commented Sep 6, 2020

I strongly recommend using performance.now().toString(36) instead of Date.now - since it offers a higher precision date (ref: https://developer.mozilla.org/en-US/docs/Web/API/Performance/now - you can get microsecond precision).

The advantage of a higher precision time is: the probability of users around the known universe generating their random ID in that exact same microsecond is very low.

Doing Math.random() in addition to this will result in randomization over-and-above an already extremely unique value.

function uid() {
  return (performance.now().toString(36)+Math.random().toString(36)).replace(/\./g,"");
};

Verified using @c0d3r111's Collision test
Collision test: 8391.403076171875ms
Total iterations: 1000000
Total collisions: 0
Total unique ids: 1000000

Unless your CPU can process more instructions in a microsecond, the value will likely never duplicate since you've moved into the next microsecond by the time the result comes out.

Window.crypto (ref https://developer.mozilla.org/en-US/docs/Web/API/Window/crypto ) as @lcherone also mentioned, provides high precision random numbers, that even inspires confidence in Cryptographic algorithms (and is thus assured to be more random than other randoms), which can be used as such:

function getRandomNumbers() {
  var array = new Uint32Array(10);
  window.crypto.getRandomValues(array);
 
  for (var i = 0; i < array.length; i++) {
    console.log(array[i] + " ");
  }
}

Combining the two, here's a final function:

function uid() {
 let a = new Uint32Array(3);
 window.crypto.getRandomValues(a);
 return (performance.now().toString(36)+Array.from(a).map(A => A.toString(36)).join("")).replace(/\./g,"");
};
@NadeemAyesh

This comment has been minimized.

Copy link

@NadeemAyesh NadeemAyesh commented Sep 28, 2020

Thank you, it was helpful :)
I have just used it in a real application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.