356
function generate(count) {
    var founded = false,
        _sym = 'abcdefghijklmnopqrstuvwxyz1234567890',
        str = '';
    while(!founded) {
        for(var i = 0; i < count; i++) {
            str += _sym[parseInt(Math.random() * (_sym.length))];
        }
        base.getID(string, function(err, res) {
            if(!res.length) {
                founded = true; // How to do it?
            }
        });
    }
    return str;
}

How to set a variable value with database query callback? How I can do it?

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
owl
  • 4,201
  • 3
  • 22
  • 28
  • @JamesAllardice, I need to understand how this can be done with a database query. Sorry, thanks. – owl Apr 27 '14 at 18:10
  • 2
    This question is incorrectly flagged as a duplicate. The linked question answers how to do it in generic javascript; the highest rated answer in this question is specific to node.js. – Mike Post Aug 12 '15 at 22:29
  • 11
    I would love to paste this as an answer: `var hexstring = crypto.randomBytes(16).toString("hex");` followed by `var guidstring = hexstring.substring(0,8) + "-" + hexstring.substring(8,12) + "-" + hexstring.substring(12,16) + "-" + hexstring.substring(16,20) + "-" + hexstring.substring(20);` – selbie Jun 19 '16 at 07:54
  • 1
    This is a good answer with `new mongo.ObjectID();` and manually https://stackoverflow.com/a/56106999/4701635 – Paresh Barad May 13 '19 at 11:45
  • @selbie Your result only *looks* like a UUID and is not always a valid UUID. This might break assumptions of any downstream code. If you just need a random identifier, then use your `hextring`, which is perfect. If you need a UUID, create one with a library in the proper format/version. – Marcel Waldvogel Jun 08 '21 at 10:00

25 Answers25

547

Install NPM uuid package (sources: https://github.com/uuidjs/uuid):

npm install uuid

and use it in your code, e.g. with ES6 imports:

import { v4 as uuidv4, v6 as uuidv6 } from 'uuid';

uuidv4();
uuidv6();

Or with CommonJS requires:

const { 
  v1: uuidv1,
  v4: uuidv4,
} = require('uuid');

uuidv1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' 
uuidv4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1' 

For

slhck
  • 36,575
  • 28
  • 148
  • 201
Vinz243
  • 9,654
  • 10
  • 42
  • 86
  • thanks, but I need to do it with a database query. :) – owl Apr 27 '14 at 18:08
  • @owl I don't understand what you mean. In SQL ? – Vinz243 Apr 27 '14 at 18:09
  • 64
    What difference does it make if it's in a db query? You have a unique id, now use it in whichever interface you use to communicate with your databse. – jraede Apr 27 '14 at 18:17
  • Any idea what's the difference between the packages uuid and node-uuid ? – ishandutta2007 Jan 17 '17 at 01:51
  • Taking a look at the source, this not not ensure **uniqueness**. This is merely a random UUID generator – Downgoat Feb 10 '17 at 03:35
  • @Downgoad No it does not assure 100% uniqueness, but is very close. So close that you can almost use it as such if you are creating documents with it. Apply a unique constrain to your database on the id field and voilá. http://stackoverflow.com/questions/1155008/how-unique-is-uuid – diutsu Apr 24 '17 at 18:40
  • 7
    @ishandutta2007 node-uuid is deprecated: "DEPRECATED: Use the uuid package instead." – diutsu Apr 24 '17 at 18:40
  • The accepted answer should show how to implement UUID generation in node.js - not how to use someone else's implementation. – papiro Jul 05 '17 at 12:17
  • i tried using with with socket-io. and seems to break require socket (2.0.3) – Khizar Ali Jul 29 '17 at 16:07
  • gives me following error when tried following in node REPL - value must be an array of bytes at generateUUID (/node_modules/uuid/lib/v35.js:29:38) – Shrikant Prabhu Jul 02 '18 at 19:35
  • i dont like that the edited version of this answer is copied from another answer. like literally – Sgnl Aug 16 '18 at 17:49
  • @Sgnl I didn't edit it, but at least the most visible answer is up to date – Vinz243 Aug 19 '18 at 11:17
  • Every time that I want to create a new GUID i have to create a new const ? `const uuidv1 = require('uuid/v1');` –  Oct 01 '18 at 10:55
  • @user3796130 no need just call the function again – Vinz243 Nov 10 '18 at 17:34
  • 4
    @Downgoat, `crypto.randomBytes(16).toString("hex")` vs. `uuidv4()`, what's a preferable option? The first one is built-in into Node.js. – Mike Jun 16 '20 at 20:11
  • 13
    nodejs `v15.6.0` now supports `crypto.randomUUID();` – Filip Seman May 17 '21 at 18:05
  • 2
    @FilipSeman According to docs it is already "Added in: v14.17.0" (https://nodejs.org/docs/latest-v14.x/api/crypto.html#crypto_crypto_randomuuid_options) which is tue and saved my day. – Cologne_Muc Sep 08 '21 at 12:41
447

The fastest possible way to create random 32-char string in Node is by using native crypto module:

const crypto = require("crypto");

const id = crypto.randomBytes(16).toString("hex");

console.log(id); // => f9b327e70bbcf42494ccb28b2d98e00e
Pono
  • 11,298
  • 9
  • 53
  • 70
  • 89
    I like this solution because no external dependency is needed. Also I found base64 version is useuful too. `crypto.randomBytes(3*4).toString('base64') //=> '9uzHqCOWI9Kq2Jdw'` – hiroshi Nov 26 '16 at 02:06
  • 17
    Is it random or unique? Please elaborate random function. – Maximi Dec 19 '17 at 18:25
  • 2
    'Generates cryptographically strong pseudo-random data.' [API](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback) – Standaa - Remember Monica May 02 '18 at 10:47
  • 7
    `crypto` is now built into node itself.. You get this warning if you npm install it: `crypto@1.0.1: This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in` – AIon May 03 '18 at 11:22
  • Make sure you don't use crypto.randomBytes() with large numbers. Also, it can be slow right after the OS boots up. Read the docs for more info: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback – Dmitrii Sorin May 30 '19 at 10:55
  • 1
    This now causes deprecation warnings. – Razze Jul 14 '19 at 15:10
  • 1
    @Pono does this gives a unique value or random value? – xetryDcoder May 24 '21 at 05:37
  • 1
    This could give a url unfriendly string since characters like `/` are included – Johnny Kontrolletti Jul 09 '21 at 17:24
  • 4
    A little one liner to help get it in UUID format `[8,4,4,4,12].map(n => crypto.randomBytes(n/2).toString("hex")).join("-")` – Greg Jan 26 '22 at 16:17
  • 1
    do we have to worry about collisions? – Jonathan Scialpi Sep 22 '22 at 04:55
  • 1
    @JonathanScialpi make a longer string, virtually no collisions – Dee Sep 22 '22 at 10:48
  • 1
    Just want to clarify that Greg's solution doesn't technically create an actual UUID, since they have certain bytes that are non-random. It should still work for all intents and purposes, however. – PoolloverNathan Mar 15 '23 at 00:03
201

Since Node 14.17.0 you can now use the built-in crypto module to generate UUIDs (UUIDv4 Flavored):

const { randomUUID } = require('crypto'); // Added in: node v14.17.0

console.log(randomUUID());

// '89rct5ac2-8493-49b0-95d8-de843d90e6ca'

For more you can explore https://nodejs.org/api/crypto.html#crypto_crypto_randomuuid_options

Note: crypto.randomUUID is three times faster than uuid. And no need to add extra dependency.

VLAZ
  • 26,331
  • 9
  • 49
  • 67
Dheeraj kumar Rao
  • 8,132
  • 3
  • 22
  • 24
54

Simple, time based, without dependencies:

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

or

Date.now().toString(36)

Output: jzlatihl


plus random number (Thanks to @Yaroslav Gaponov's answer)

(new Date()).getTime().toString(36) + Math.random().toString(36).slice(2)

Output jzlavejjperpituute

Robert Brisita
  • 5,461
  • 3
  • 36
  • 35
safrazik
  • 1,517
  • 10
  • 14
  • 6
    Beware: I highly discourage this solution for any important app: such client's "time-dependent" unique id is an absolutely **NO-GO** . though adding random number (as mention in the end of th epost) helps it. – T.Todua Nov 07 '22 at 12:53
47

edit: shortid has been deprecated. The maintainers recommend to use nanoid instead.


Another approach is using the shortid package from npm.

It is very easy to use:

var shortid = require('shortid');
console.log(shortid.generate()); // e.g. S1cudXAF

and has some compelling features:

ShortId creates amazingly short non-sequential url-friendly unique ids. Perfect for url shorteners, MongoDB and Redis ids, and any other id users might see.

  • By default 7-14 url-friendly characters: A-Z, a-z, 0-9, _-
  • Non-sequential so they are not predictable.
  • Can generate any number of ids without duplicates, even millions per day.
  • Apps can be restarted any number of times without any chance of repeating an id.
str
  • 42,689
  • 17
  • 109
  • 127
  • "Apps can be restarted any number of times without any chance of repeating an id.?" Can you show me how shortid works? – nhaht Nov 06 '18 at 13:38
  • @NavyFlame Here you go: https://github.com/dylang/shortid or more specifically https://github.com/dylang/shortid/issues/95 – str Nov 06 '18 at 13:44
  • 2
    "shortid is deprecated, because the architecture is unsafe. we instead recommend Nano ID, which has the advantage of also being significantly faster than shortid" https://github.com/ai/nanoid – Mike Jan 11 '21 at 04:23
28

It's been some time since I used node.js, but I think I might be able to help.

Firstly, in node, you only have a single thread and are supposed to use callbacks. What will happen with your code, is that base.getID query will get queued up by for execution, but the while loop will continusouly run as a busy loop pointlessly.

You should be able to solve your issue with a callback as follows:

function generate(count, k) {
    var _sym = 'abcdefghijklmnopqrstuvwxyz1234567890',
    var str = '';

    for(var i = 0; i < count; i++) {
        str += _sym[parseInt(Math.random() * (_sym.length))];
    }
    base.getID(str, function(err, res) {
        if(!res.length) {
          k(str)                   // use the continuation
        } else generate(count, k)  // otherwise, recurse on generate
    });
}

And use it as such

generate(10, function(uniqueId){
  // have a uniqueId
})

I haven't coded any node/js in around 2 years and haven't tested this, but the basic idea should hold – don't use a busy loop, and use callbacks. You might want to have a look at the node async package.

rafalio
  • 3,928
  • 4
  • 30
  • 33
  • 13
    Math.random is a poor choice when a truly random ID is needed, especially if it needs to be unpredictable / cryptographically secure. – Jecho Jekov Apr 24 '18 at 14:15
22

node-uuid is deprecated so please use uuid

npm install uuid --save
// Generate a v1 UUID (time-based) 
const uuidV1 = require('uuid/v1');
uuidV1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' 

// Generate a v4 UUID (random) 
const uuidV4 = require('uuid/v4');
uuidV4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1' 

Npm link

Praveena
  • 6,340
  • 2
  • 40
  • 53
18

More easy and without addition modules

Math.random().toString(26).slice(2)
slfan
  • 8,950
  • 115
  • 65
  • 78
Yaroslav Gaponov
  • 1,997
  • 13
  • 12
  • 3
    I think it depends on length. so you can extend this code like this inline `function getId(mask) { return mask.replace(/[x]/gi, () => { return Math.random().toString(26)[5]; }) } console.log(getId('xxxx-xxxx-xxxx-xxxx-xxxx-xxxx'));` – Yaroslav Gaponov Dec 04 '17 at 07:10
  • 9
    Math.random is a poor choice when a truly random ID is needed, especially if it needs to be unpredictable / cryptographically secure. – Jecho Jekov Apr 24 '18 at 14:15
  • 2
    This will not generate a truly universally unique id. – vicg Jan 20 '19 at 19:43
  • @JechoJekov "truly random" ? I doubt it – jdrake May 09 '19 at 14:23
  • Yes [YaroslavGaponov](https://stackoverflow.com/users/3778960/yaroslav-gaponov) could be correct as the chances of fractions being the same in a real space [0, 1] is 0. Wrote code to generate 1,000,000 Math.random() and could not find any duplicates. ```random_numbers = [] for (i = 0; i < 1000000; i++) { random_numbers.push(Math.random()) } if (i === 1000000) { console.log("Before checking duplicate") console.log(random_numbers.length) console.log("After checking duplicate") random_set = new Set(random_numbers) console.log([...random_set].length) }``` – Yi Xiang Chong May 10 '20 at 05:33
  • @YiXiangChong, if there's no chance of duplicates with "Math.random()", there's a problem. It's no longer randomness. – Patrice Thimothee Jul 18 '22 at 23:08
13

If you use node v15.6.0+ us can use crypto.randomUUID([options]). Full documentation here.

user1079877
  • 9,008
  • 4
  • 43
  • 54
12

to install uuid

npm install --save uuid

uuid is updated and the old import

const uuid = require('uuid/v4');

is not working and we should now use this import

const {v4: uuid} = require('uuid');

and for using it use as a function like this

const  createdPlace = {
    id: uuid(),
    title,
    description,
    location: coordinates,
    address,
    creator
  };
Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Rohan Devaki
  • 2,931
  • 1
  • 14
  • 22
9

My 5 cents:

const crypto = require('crypto');

const generateUuid = () => {
  return [4, 2, 2, 2, 6] // or 8-4-4-4-12 in hex
    .map(group => crypto.randomBytes(group).toString('hex'))
    .join('-');
};

Pono's string lacked hyphens sadly, so it did not conform to the uuid standard, which is what I believe most people came here for.

> generateUuid();
'143c8862-c212-ccf1-e74e-7c9afa78d871'
> generateUuid();
'4d02d4d6-4c0d-ea6b-849a-208b60bfb62e'
Klesun
  • 12,280
  • 5
  • 59
  • 52
  • crypto is deprecated as far as I see. https://www.npmjs.com/package/crypto Recommended https://nodejs.org/api/crypto.html So to note : You don't need to run `npm install crypto` - just reference it as above. – Pogrindis Feb 10 '23 at 00:26
  • Yeah, `crypto` is a built-in module. The deprecated module in npm is just some random package that incidentally has same name. – Klesun Feb 10 '23 at 12:45
5

If some one needs cryptographic-strong UUID, there is solution for that as well.

https://www.npmjs.com/package/generate-safe-id

npm install generate-safe-id

Why not UUIDs?

Random UUIDs (UUIDv4) do not have enough entropy to be universally unique (ironic, eh?). Random UUIDs have only 122 bits of entropy, which suggests that a duplicate will occur after only 2^61 IDs. Additionally, some UUIDv4 implementations do not use a cryptographically strong random number generator.

This library generates 240-bit IDs using the Node.js crypto RNG, suggesting the first duplicate will occur after generating 2^120 IDs. Based on the current energy production of the human race, this threshold will be impossible to cross for the foreseeable future.

var generateSafeId = require('generate-safe-id');

var id = generateSafeId();
// id == "zVPkWyvgRW-7pSk0iRzEhdnPcnWfMRi-ZcaPxrHA"
ch3ll0v3k
  • 336
  • 3
  • 9
  • 11
    This is answer may no longer work for users due to `generate-safe-id` being abandoned AND security vulnerabilities not being fixed (as of August 2018) – dannypaz Aug 06 '18 at 23:46
3

i want to use this

class GUID {
    Generate() {
    const hex = "0123456789ABCDEF";
    const model = "xxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx";
    var str = "";
    for (var i = 0; i < model.length; i++) {
      var rnd = Math.floor(Math.random() * hex.length);
      str += model[i] == "x" ?  hex[rnd] : model[i] ;
    }
    return str.toLowerCase();
  }
}
 
console.log(new GUID().Generate());
console.log(new GUID().Generate());
console.log(new GUID().Generate());
console.log(new GUID().Generate());
console.log(new GUID().Generate());
hossein sedighian
  • 1,711
  • 1
  • 13
  • 16
2

nanoid achieves exactly the same thing that you want.

Example usage:

const { nanoid } = require("nanoid")

console.log(nanoid())
//=> "n340M4XJjATNzrEl5Qvsh"
Richie Bendall
  • 7,738
  • 4
  • 38
  • 58
2

You can use urid package npm install urid

import urid from 'urid';

urid(); // qRpky22nKJ4vkbFZ

Read full docs here: https://www.npmjs.com/package/urid

// Set the size
urid(8); //ZDJLC0Zq

// Use the character set
urid('num'); // 4629118294212196
urid('alpha'); // ebukmhyiagonmmbm
urid('alphanum'); // nh9glmi1ra83979b

// Use size with character set
urid(12, 'alpha'); // wwfkvpkevhbg

// use custom character set
urid(6, '0123456789ABCDEF'); // EC58F3
urid('0123456789ABCDEF'); // 6C11044E128FB44B

// some more samples
urid()               // t8BUFCUipSEU4Ink
urid(24)             // lHlr1pIzAUAOyn1soU8atLzJ
urid(8, 'num')       // 12509986
urid(8, 'alpha')     // ysapjylo
urid(8, 'alphanum')  // jxecf9ad

// example of all character sets
urid('num')          // 5722278852141945
urid('alpha')        // fzhjrnrkyxralgpl
urid('alphanum')     // l5o4kfnrhr2cj39w
urid('Alpha')        // iLFVgxzzUFqxzZmr
urid('ALPHA')        // ALGFUIJMZJILJCCI
urid('ALPHANUM')     // 8KZYKY6RJWZ89OWH
urid('hex')          // 330f726055e92c51
urid('HEX')          // B3679A52C69723B1

// custom character set
urid('ABCD-')        // ACA-B-DBADCD-DCA
1

I am using the following and it is working fine plus without any third-party dependencies.

const {
  randomBytes
} = require('crypto');

const uid = Math.random().toString(36).slice(2) + randomBytes(8).toString('hex') + new Date().getTime();
  • 4
    Note that the UUID is not just random bits, and follow a specific structure. An UUID generated from random number (or encoding arbitrary information) is defined in RFC4122 as "version 4", and has two specific group of bits, length 2 and 4 respectively, set to specific values. The remaining 122 bits can be anything. But they are non-contiguous. https://tools.ietf.org/html/rfc4122#section-4.4 – kkm inactive - support strike Sep 13 '20 at 04:04
1

The solutions here are old and now deprecated: https://github.com/uuidjs/uuid#deep-requires-now-deprecated

Use this:

npm install uuid

//add these lines to your code
const { v4: uuidv4 } = require('uuid');
var your_uuid = uuidv4();
console.log(your_uuid);
Rob
  • 869
  • 9
  • 11
1

used https://www.npmjs.com/package/uniqid in npm

npm i uniqid

It will always create unique id's based on the current time, process and machine name.

  • With the current time the ID's are always unique in a single process.
  • With the Process ID the ID's are unique even if called at the same time from multiple processes.
  • With the MAC Address the ID's are unique even if called at the same time from multiple machines and processes.

Features:-

  • Very fast
  • Generates unique id's on multiple processes and machines even if called at the same time.
  • Shorter 8 and 12 byte versions with less uniqueness.
Jayani Sumudini
  • 1,409
  • 2
  • 22
  • 29
1

Extending from YaroslavGaponov's answer, the simplest implementation is just using Math.random().

Math.random()

Mathematically, the chances of fractions being the same in a real space [0, 1] is theoretically 0. Probability-wise it is approximately close to 0 for a default length of 16 decimals in node.js. And this implementation should also reduce arithmetic overflows as no operations are performed. Also, it is more memory efficient compared to a string as Decimals occupy less memory than strings.

I call this the "Fractional-Unique-ID".

Wrote code to generate 1,000,000 Math.random() numbers and could not find any duplicates (at least for default decimal points of 16). See code below (please provide feedback if any):

random_numbers = [] 
for (i = 0; i < 1000000; i++) { 
   random_numbers.push(Math.random()); 
   //random_numbers.push(Math.random().toFixed(13)) //depends decimals default 16 
} 

if (i === 1000000) { 
   console.log("Before checking duplicate"); 
   console.log(random_numbers.length); 
   console.log("After checking duplicate"); 
   random_set = new Set(random_numbers); // Set removes duplicates
   console.log([...random_set].length); // length is still the same after removing
} 
Yi Xiang Chong
  • 744
  • 11
  • 9
  • Also, it depends on the number of decimals. I found that above 13 decimals ```random_numbers.push(Math.random().toFixed(13))``` still give the same length – Yi Xiang Chong May 10 '20 at 07:36
1

Here is one benchmark for current solutions refer to nanoid benchmark

import { v4 as uuid4 } from 'uuid'
import benchmark from 'benchmark'
import shortid from 'shortid'

let suite = new benchmark.Suite()

suite
  .add('crypto.randomUUID', () => {
    crypto.randomUUID()
  })
  .add('nanoid', () => {
    nanoid()
  })
  .add('uuid v4', () => {
    uuid4()
  })
  .add("math.random", () => {
    (new Date()).getTime().toString(36) + Math.random().toString(36).slice(2)
  })
  .add('crypto.randomBytes', () => {
    crypto.randomBytes(32).toString('hex')
  })
  .add('shortid', () => {
    shortid()
  })
  .on('cycle', event => {
    let name = event.target.name
    let hz = formatNumber(event.target.hz.toFixed(0)).padStart(10)

    process.stdout.write(`${name}${pico.bold(hz)}${pico.dim(' ops/sec')}\n`)
  })
  .run()

The result is

node ./test/benchmark.js
crypto.randomUUID         13,281,440 ops/sec
nanoid                     3,278,757 ops/sec
uuid v4                    1,117,140 ops/sec
math.random                1,206,105 ops/sec
crypto.randomBytes           280,199 ops/sec
shortid                       30,728 ops/sec

Test env:

  • 2.6 GHz 6Cores Intel Core i7 MacOS
  • Node v16.17.0
zangw
  • 43,869
  • 19
  • 177
  • 214
1

const uniqueId = self.crypto.randomUUID();
console.log(uniqueId)
  • The randomUUID() method of the Crypto interface is used to generate a v4 UUID using a cryptographically secure random number generator.
  • Return A string containing a randomly generated, 36 character long v4 UUID.
Md Shayon
  • 79
  • 5
0

Generates cryptographically strong pseudorandom data. The size argument is a number indicating the number of bytes to generate.

// Asynchronous
const {
  randomBytes,
} = require('crypto');

randomBytes(256, (err, buf) => {
  if (err) throw err;
  console.log(`${buf.length} bytes of random data: unique random ID ${buf.toString('hex')}`);
});

Know more

MD SHAYON
  • 7,001
  • 45
  • 38
0

For me, the easiest way to get unique id is the time, and I use hash for that example

const hash = require('object-hash');
const user = { ..., iat: Date.now() }
const user_id = hash(user)

console.log(user_id) // ex. 49686bab1a2276e0b1bd61ccc86f8156

and that is how I actually get unique identifier in any aspect. because in real world time never repeats.

Marvin
  • 647
  • 7
  • 15
0

var uid = new ShortUniqueId(); var id = uid();

//add cdn link of ShortUniqueId in index.html body just above your script.js

  • I would recommend adding all steps to the suggested answer instead of writing "add cdn link of ShortUniqueId" – AlexHalkin Mar 01 '23 at 17:33
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 01 '23 at 17:34
-1

let count = 0;
let previous = 0;
const generateUniqueId = () => {
  const time = new Date().getTime()
  count = time > previous ? 0 : (++count)
  const uid = time + count
  previous = uid
  return uid
}