285
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
  • 17,282
  • 10
  • 73
  • 131
owl
  • 3,451
  • 2
  • 21
  • 27
  • @JamesAllardice, I need to understand how this can be done with a database query. Sorry, thanks. – owl Apr 27 '14 at 18:10
  • 1
    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

19 Answers19

499

Install NPM uuid package (sources: https://github.com/kelektiv/node-uuid):

npm install uuid

and use it in your code:

var uuid = require('uuid');

Then create some ids ...

// 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'

** UPDATE 3.1.0
The above usage is deprecated, so use this package like this:

const uuidv1 = require('uuid/v1');
uuidv1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' 

const uuidv4 = require('uuid/v4');
uuidv4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1' 

** UPDATE 7.x
And now the above usage is deprecated as well, so use this package like this:

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

uuidv1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' 
uuidv4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1' 
Kyle Baker
  • 2,998
  • 2
  • 23
  • 29
Vinz243
  • 9,060
  • 10
  • 40
  • 79
  • 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
  • 63
    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) – Khizer 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
  • 3
    @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
  • 8
    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
  • thank you for the update, you are the best. – Elizabeth Jan 17 '22 at 16:42
393

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
  • 10,532
  • 9
  • 50
  • 67
  • 78
    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
  • 13
    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
  • 5
    @owl I feel like this is really the best answer, would you consider updating this to the chosen answer? – user3692823 Apr 29 '20 at 20:53
  • 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 – Tim Jul 09 '21 at 17:24
  • This is also a good answer... as it is an inbuilt module. Nice – Elizabeth Jan 17 '22 at 16:44
  • 2
    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
98

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
  • 22,934
  • 9
  • 44
  • 60
Dheeraj kumar Rao
  • 2,447
  • 1
  • 17
  • 18
  • 1
    The comment is incorrect. crypto.randomUUID() works in v14 of node https://nodejs.org/dist/latest-v14.x/docs/api/crypto.html#crypto_crypto_randomuuid_options – Ryan Pfister Jun 04 '21 at 18:22
  • You may have to install `@types/node` for this to work. – Justin Apr 12 '22 at 16:11
46

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
  • 4,684
  • 2
  • 33
  • 33
safrazik
  • 1,379
  • 9
  • 13
43

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
  • 38,402
  • 15
  • 99
  • 123
  • "Apps can be restarted any number of times without any chance of repeating an id.?" Can you show me how shortid works? – Navy Flame 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
  • 1
    "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 Stead 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,828
  • 4
  • 28
  • 32
  • 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
  • 5,870
  • 1
  • 39
  • 53
17

More easy and without addition modules

Math.random().toString(26).slice(2)
slfan
  • 8,665
  • 115
  • 63
  • 77
Yaroslav Gaponov
  • 1,793
  • 11
  • 11
  • 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
  • 8
    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
  • 1
    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
10

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 funciton like this

const  createdPlace = {
    id: uuid(),
    title,
    description,
    location:coordinates,
    address,
    creator
  };
Rohan Devaki
  • 2,271
  • 1
  • 12
  • 19
7

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

user1079877
  • 8,449
  • 4
  • 41
  • 47
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
  • 236
  • 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
5

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
  • 9,951
  • 5
  • 51
  • 44
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,379
  • 1
  • 10
  • 13
2

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 Sep 13 '20 at 04:04
2

nanoid achieves exactly the same thing that you want.

Example usage:

const { nanoid } = require("nanoid")

console.log(nanoid())
//=> "n340M4XJjATNzrEl5Qvsh"
Richie Bendall
  • 5,657
  • 3
  • 32
  • 49
  • Hi, hope you are good. Can you please have a look at my question. I am trying to use uuid but it does not change until node server restarts. https://stackoverflow.com/questions/65479245/nodejs-multer-aws-s3 – kd12345 Dec 30 '20 at 05:37
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,291
  • 1
  • 19
  • 27
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
  • 606
  • 9
  • 7
  • 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
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,911
  • 47
  • 35