Categories
guid javascript uuid

How do I create a GUID / UUID?

4972

How do I create GUIDs (globally-unique identifiers) in JavaScript? The GUID / UUID should be at least 32 characters and should stay in the ASCII range to avoid trouble when passing them around.

I’m not sure what routines are available on all browsers, how “random” and seeded the built-in random number generator is, etc.

6

  • 31

    GUIDs when repesented as as strings are at least 36 and no more than 38 characters in length and match the pattern ^\{?[a-zA-Z0-9]{36}?\}$ and hence are always ascii.

    Sep 19, 2008 at 20:35

  • 3

    David Bau provides a much better, seedable random number generator at davidbau.com/archives/2010/01/30/… I wrote up a slightly different approach to generating UUIDs at blogs.cozi.com/tech/2010/04/generating-uuids-in-javascript.html

    May 4, 2010 at 23:09

  • 1

    Weird that no one has mentioned this yet but for completeness, there’s a plethora of guid generators on npm I’m willing to bet most of them work in browser too.

    Feb 3, 2014 at 15:54

  • 1

    If anyone wants more options like different versions of the uuid and non standard guid support, REST based uuid generation services like these [fungenerators.com/api/uuid ] are an attractive option too.

    – dors

    Dec 15, 2020 at 16:20

  • 1

    Some 12 years later with BigInt and ES6 classes, other techniques that yield rates of 500,000 uuid/sec can be done. See reference

    Dec 30, 2020 at 6:34

2590

UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDentifier), according to RFC 4122, are identifiers designed to provide certain uniqueness guarantees.

While it is possible to implement RFC-compliant UUIDs in a few lines of JavaScript code (e.g., see @broofa’s answer, below) there are several common pitfalls:

  • Invalid id format (UUIDs must be of the form “xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx“, where x is one of [0-9, a-f] M is one of [1-5], and N is [8, 9, a, or b]
  • Use of a low-quality source of randomness (such as Math.random)

Thus, developers writing code for production environments are encouraged to use a rigorous, well-maintained implementation such as the uuid module.

11

  • 207

    Actually, the RFC allows for UUIDs that are created from random numbers. You just have to twiddle a couple of bits to identify it as such. See section 4.4. Algorithms for Creating a UUID from Truly Random or Pseudo-Random Numbers: rfc-archive.org/getrfc.php?rfc=4122

    Sep 19, 2008 at 20:28

  • 62

    This should not be the accepted answer. It does not actually answer the question – instead encouraging the import of 25,000 lines of code for something you can do with one line of code in any modern browser.

    Jul 8, 2020 at 0:36


  • 1

    @AbhiBeckert the answer is from 2008 and for node.js projects it might be valid to choose a dependency more over project size

    – Phil

    Sep 29, 2020 at 13:48

  • 6

    @Phil this is a “highly active question”, which means it should have an excellent answer with a green tick. Unfortunately that’s not the case. There is nothing wrong or incorrect with this answer (if there was, I’d edit the answer) – but another far better answer exists below and I think it should be at the top of the list. Also the question is specifically relating to javascript in a browser, not node.js.

    Oct 8, 2020 at 3:47


  • 2

    I challenge the claim that Math.random is that low of a quality of randomness. v8.dev/blog/math-random. As you can see, it’s passes a good test suite, and the same algorithm is used by v8, FF and Safari. And the RFC states, pseudo-random numbers are acceptable for UUIDs

    – Munawwar

    May 27, 2021 at 8:38

2590

UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDentifier), according to RFC 4122, are identifiers designed to provide certain uniqueness guarantees.

While it is possible to implement RFC-compliant UUIDs in a few lines of JavaScript code (e.g., see @broofa’s answer, below) there are several common pitfalls:

  • Invalid id format (UUIDs must be of the form “xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx“, where x is one of [0-9, a-f] M is one of [1-5], and N is [8, 9, a, or b]
  • Use of a low-quality source of randomness (such as Math.random)

Thus, developers writing code for production environments are encouraged to use a rigorous, well-maintained implementation such as the uuid module.

11

  • 207

    Actually, the RFC allows for UUIDs that are created from random numbers. You just have to twiddle a couple of bits to identify it as such. See section 4.4. Algorithms for Creating a UUID from Truly Random or Pseudo-Random Numbers: rfc-archive.org/getrfc.php?rfc=4122

    Sep 19, 2008 at 20:28

  • 62

    This should not be the accepted answer. It does not actually answer the question – instead encouraging the import of 25,000 lines of code for something you can do with one line of code in any modern browser.

    Jul 8, 2020 at 0:36


  • 1

    @AbhiBeckert the answer is from 2008 and for node.js projects it might be valid to choose a dependency more over project size

    – Phil

    Sep 29, 2020 at 13:48

  • 6

    @Phil this is a “highly active question”, which means it should have an excellent answer with a green tick. Unfortunately that’s not the case. There is nothing wrong or incorrect with this answer (if there was, I’d edit the answer) – but another far better answer exists below and I think it should be at the top of the list. Also the question is specifically relating to javascript in a browser, not node.js.

    Oct 8, 2020 at 3:47


  • 2

    I challenge the claim that Math.random is that low of a quality of randomness. v8.dev/blog/math-random. As you can see, it’s passes a good test suite, and the same algorithm is used by v8, FF and Safari. And the RFC states, pseudo-random numbers are acceptable for UUIDs

    – Munawwar

    May 27, 2021 at 8:38

933

I really like how clean Broofa’s answer is, but it’s unfortunate that poor implementations of Math.random leave the chance for collision.

Here’s a similar RFC4122 version 4 compliant solution that solves that issue by offsetting the first 13 hex numbers by a hex portion of the timestamp, and once depleted offsets by a hex portion of the microseconds since pageload. That way, even if Math.random is on the same seed, both clients would have to generate the UUID the exact same number of microseconds since pageload (if high-perfomance time is supported) AND at the exact same millisecond (or 10,000+ years later) to get the same UUID:

function generateUUID() { // Public Domain/MIT
    var d = new Date().getTime();//Timestamp
    var d2 = ((typeof performance !== 'undefined') && performance.now && (performance.now()*1000)) || 0;//Time in microseconds since page-load or 0 if unsupported
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.random() * 16;//random number between 0 and 16
        if(d > 0){//Use timestamp until depleted
            r = (d + r)%16 | 0;
            d = Math.floor(d/16);
        } else {//Use microseconds since page-load if supported
            r = (d2 + r)%16 | 0;
            d2 = Math.floor(d2/16);
        }
        return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
}

var onClick = function(){
    document.getElementById('uuid').textContent = generateUUID();
}
onClick();
#uuid { font-family: monospace; font-size: 1.5em; }
<p id="uuid"></p>
<button id="generateUUID" onclick="onClick();">Generate UUID</button>

Here’s a fiddle to test.


Modernized snippet for ES6

const generateUUID = () => {
  let
    d = new Date().getTime(),
    d2 = (performance && performance.now && (performance.now() * 1000)) || 0;
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
    let r = Math.random() * 16;
    if (d > 0) {
      r = (d + r) % 16 | 0;
      d = Math.floor(d / 16);
    } else {
      r = (d2 + r) % 16 | 0;
      d2 = Math.floor(d2 / 16);
    }
    return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16);
  });
};

const onClick = (e) => document.getElementById('uuid').textContent = generateUUID();

document.getElementById('generateUUID').addEventListener('click', onClick);

onClick();
#uuid { font-family: monospace; font-size: 1.5em; }
<p id="uuid"></p>
<button id="generateUUID">Generate UUID</button>

8

  • 36

    Bear in mind, new Date().getTime() is not updated every millisecond. I’m not sure how this affects the expected randomness of your algorithm.

    – devios1

    Mar 18, 2012 at 17:27

  • 91

    performance.now would be even better. Unlike Date.now, the timestamps returned by performance.now() are not limited to one-millisecond resolution. Instead, they represent times as floating-point numbers with up to microsecond precision. Also unlike Date.now, the values returned by performance.now() always increase at a constant rate, independent of the system clock which might be adjusted manually or skewed by software such as the Network Time Protocol.

    Mar 13, 2014 at 4:25


  • The actual time resolution may or may not be 17 ms (1/60 second), not 1 ms.

    Dec 30, 2020 at 3:28

  • Would Crypto.getRandomValues fix the main problems with Math.random??

    – John

    Apr 1, 2021 at 22:07

  • 1

    @NaveenReddyMarthala Node.js by default runs JavaScript in strict mode, which unfortunately doesn’t allow boolean logic operators to shorthand check the truthiness of undefined variables. To fix this, try replacing var d2 = (performance .. with var d2 = (typeof performance !== 'undefined' .. as in the update version. The other option (which will actually utilize the enhanced precision of performance with Node.js rather than throwing it away) is to re-add const { performance } = require('perf_hooks'); in your requirements.

    – Briguy37

    Sep 13, 2021 at 14:47